4

bookshelf で checkit を使用しようとしていますが、checkit ルールを追加して意図的に違反した後、promise#catch ブロックがエラーを適切にキャッチしていないようです。(ここでのキャッチの使用を完全に誤解している可能性もあります)

var validationRules = new Checkit({
    email: 'required',
    password: 'required'
});

var User = bookshelf.Model.extend({
    tableName: 'users',

    initialize: function() {
        this.on('saving', this.validateSave);
    },
    validateSave: function() {
        validationRules.run(this.attributes);
    }
});

User.forge({}).save().then(function(validated) {
    console.log('this shouldnt trigger');
}).catch(function(err) { // this doesnt seem to be working the way I expect
    console.log(e.message);
});

空のユーザー オブジェクトを作成すると、次の未処理のエラー スタック トレースが表示され、DB クエリが構築されていることもわかります (本棚プロジェクトと「保存」イベントにフックするとどうなるかについては別の問題である可能性があります)。

Possibly unhandled Checkit Errors - email: The email is required; password: The password is     required
    at checkit/checkit.js:105:23
    at tryCatch1 (bluebird/js/main/util.js:45:21)
    at Promise._callHandler (bluebird/js/main/promise.js:597:13)
    at Promise._settlePromiseFromHandler (bluebird/js/main/promise.js:607:18)
    at Promise._settlePromiseAt (checkit/node_modules/bluebird/js/main/promise.js:769:18)
    at Promise._settlePromises (checkit/node_modules/bluebird/js/main/promise.js:884:14)
    at Async._drainQueue (checkit/node_modules/bluebird/js/main/async.js:98:12)
    at Async._drainQueues (checkit/node_modules/bluebird/js/main/async.js:103:10)
    at Async.drainQueues (checkit/node_modules/bluebird/js/main/async.js:37:14)
    at process._tickCallback (node.js:415:13)
{ __cid: '__cid1',
  method: 'insert',
  options: undefined,
  bindings: [],
  sql: 'insert into `users` () values ()' }
ER_NO_DEFAULT_FOR_FIELD: Field 'email' doesn't have a default value

これについて 2 つの質問があります。

  1. debug: trueknex 構成でオンにしているため、スタックトレースと の間のブロックは準備された SQL ステートメントのようER_NO_DEFAULT_FOR_FIELDです。モデル レベルで検証エラーをキャッチするために Checkit を導入したのに、SQL がまだ実行されているのはなぜですか?
  2. #catch ブロックを正しい方法で使用していますか? もしそうなら、なぜ私は未処理のエラースタックトレースを取得するのですか? ( e.message#catch 関数の結果は、実際には Checkit からではなく MySQL から来ているように見えます) そうでない場合、ここでエラーをより適切に処理する正しい方法は何ですか?

これまでの主な情報源は、bookshelf.js ドキュメント ( http://bookshelfjs.org/ ) と Checkit リポジトリ ( https://github.com/tgriesser/checkit )です。

4

1 に答える 1

4

Checkit は Promise を返します。Promise は戻り値を使用して相互に連携するため、検証がいつ完了したかを本棚に知らせないようreturnにする必要があります。checkit.run

ブルーバード (根底にある約束) は、あなたが気づいていない拒絶があるかもしれないことを知らせています。コードを修正するには、次のように変更する必要があります。

validationRules.run(this.attributes);

に:

return validationRules.run(this.attributes);

validateSave関数内で、約束を連鎖させることができます。

于 2015-01-02T14:39:28.517 に答える