ExpressJSアプリケーションのBookshelf Userモデルに非常に基本的なログインメソッドを追加していますが、Userモデルのlogin関数が返すという拒否された約束からエラーをキャッチできません。私はhttp://bookshelfjs.org/#Model-static-extendのドキュメントのBookshelfのログイン例を見ていますが、その例ではBluebirdが使用されていますが、組み込みのES6の約束で同じことをしようとしています。 UserモデルでES6の約束とBookshelfJSのエラーをキャッチする
私のログイン方法:
userModel.js
function login(email, password) {
return new Promise((resolve, reject) => {
User.where('email', email)
.fetch({ require: true })
.then(user => {
bcrypt.compare(password, user.get('password'), (err, matched) => {
if (!matched) return reject(new Error('Password didn\'t match!'));
resolve(user);
});
});
});
ログインを実装し、本棚User
モデルからUser.login
を呼び出すコントローラのアクション:
usersAuthController。 js
function logUserIn(req, res) {
new User().login(req.body.email, req.body.password)
.then(user => res.json({ message: 'Login succeeded!' }))
.catch(User.NotFoundError,() => res.status(404).json({ error: 'User not found!' }) // catch #1
.catch(err => res.status(401).json({ err: err.message })); // catch #2
}
私の意図は、login()
はBookshelfのUser.fetch
メソッドが指定された電子メールでユーザーを見つけることができない場合、拒否された約束を返すことができます。その場合、.catch(User.NotFoundError ...)
(catch#1)行はそれを捕まえて404を返します。login()
に渡されたパスワードがユーザのパスワードと一致しないと判断した場合、bcrypt
は拒否されたPromiseを返すつもりです。私は間違ったパスワードを入れた場合は、「キャッチオール」(2キャッチ#)User.NotFoundError
catchステートメント以下は401
を返す必要があり、上記のコードでlogUserIn()
コントローラのアクションはエラーメッセージ{ error: "Cannot set property 'message' of undefined" }
と#2をキャッチするために行きますメッセージの代わりに私はlogin()
で拒否しました。存在しない電子メールを入れた場合、応答は送信されず、エラーUnhandled rejection CustomError: EmptyResponse
がコンソールにスローされます。有効な入力のみが有効です。
修正の試み:がモデルの代わりにUser.NotFoundError
を直接キャッチします。
loginメソッドは、現在のように見えるように、私はUserモデルにキャッチ#1を移動:
userModel.js
function login(email, password) {
return new Promise((resolve, reject) => {
User.where('email', email)
.fetch({ require: true })
.then(user => {
bcrypt.compare(password, user.get('password'), (err, matched) => {
if (!matched) return reject(new Error('Password didn\'t match!'));
resolve(user);
});
})
.catch(User.NotFoundError,() => reject({ error: 'User not found!' }));
});
この方法で、私はエラー(間違ったパスワードの両方をキャッチすることができますし、存在しない電子メール)が正しく表示されますが、この方法でコントローラにステータスコードを指定することはできません。指定された電子メールを持つユーザが見つからなかった場合は404を返すべきですが、パスワードが間違っていれば401を返すべきですが、両方のエラーは両方ともcatch-all(catch#2)にコントローラーアクション(常に401を返します)。私は.catch(User.NotFoundError,() => reject({ name: 'NotFoundError', message: 'User not found!' }))
を行うことができ、コントローラのアクションで私はを取得していますエラーの種類を確認することができますが、それは本当に厄介なようで、これら.catch
文を持っていることのポイントを見逃しUser
モデルでは、この問題を解決するための
。
のモデルのログイン方法とその他のエラーからUser.NotFoundError
をキャッチする方法はありますか?なぜ私は最初に働いていたセットアップ、usersControllerにcatch
の両方のステートメントがあるのでしょうか?そして、Cannot set property 'message' of undefined'
とCustomError: EmptyResponse
のエラーはどういう意味ですか(BookshelfのBluebirdの約束と組み込みのES6の約束を混ぜることと何か関係があります)?これを処理する最善の方法は何ですか?
は避けてください[ 'Promise'コンストラクタアンチパターン](http://stackoverflow.com/q/23803743/1048572)!その 'login'機能では、' bcrypt.compare'だけを約束するべきです。 – Bergi