Bluebird Promiseライブラリを使用しています。約束を連鎖させ、特定の約束エラーをキャッチしたいと思います。ここに私がやっていることがあります:
getSession(sessionId)
.catch(function (err) {
next(new Error('session not found'));
})
.then(function (session) {
return getUser(session.user_id);
})
.catch(function (err) {
next(new Error('user not found'));
})
.then(function (user) {
req.user = user;
next();
});
ただし、getSession
によってエラーがスローされた場合、2つのcatch
と2番目のthen
が呼び出されます。最初のcatch
でエラーの伝播を停止したいので、2番目のcatch
はgetUser
がスローされたときにのみ呼び出され、2番目のthen
はgetUser
が成功したとき。どうする?
.catch
メソッドによって返されるpromiseは、コールバックの結果で解決されます。チェーンの伝播を停止するだけではありません。チェーンを分岐する必要があります。
var session = getSession(sessionId);
session.catch(function (err) { next(new Error('session not found')); });
var user = session.get("user_id").then(getUser);
user.catch(function (err) { next(new Error('user not found')); })
user.then(function (user) {
req.user = user;
next();
});
または、then
への2番目のコールバックを使用します。
getSession(sessionId).then(function(session) {
getUser(session.user_id).then(function (user) {
req.user = user;
next();
}, function (err) {
next(new Error('user not found'));
});
}, function (err) {
next(new Error('session not found'));
});
あるいは、エラーをチェーン全体に伝播し、最後にのみnext
を呼び出すほうが良い方法です。
getSession(sessionId).catch(function (err) {
throw new Error('session not found'));
}).then(function(session) {
return getUser(session.user_id).catch(function (err) {
throw new Error('user not found'));
})
}).then(function (user) {
req.user = user;
return null;
}).then(next, next);
Promiseにbluebirdを使用しているため、実際にはすべての関数の後にcatchステートメントは必要ありません。すべてのthenを連結して、1回のキャッチですべてを閉じることができます。このようなもの:
getSession(sessionId)
.then(function (session) {
return getUser(session.user_id);
})
.then(function (user) {
req.user = user;
next();
})
.catch(function(error){
/* potentially some code for generating an error specific message here */
next(error);
});
エラーメッセージがエラーの内容を伝えていると仮定すると、「セッションが見つかりません」や「ユーザーが見つかりません」などのエラー固有のメッセージを送信することは可能ですが、エラーメッセージを調べてその内容を確認する必要があります君は。
注:エラーがあるかどうかに関係なく、おそらくnextを呼び出す理由があると確信していますが、エラーが発生した場合はconsole.error(error)をスローすると便利です。または、console.error、res.send(404)、または同様のもののいずれかに関係なく、他のエラー処理関数を使用できます。
私はそれをそのように使用しています:
getSession(x)
.then(function (a) {
...
})
.then(function (b) {
if(err){
throw next(new Error('err msg'))
}
...
})
.then(function (c) {
...
})
.catch(next);