Promiseのcatchで例外を投げてもExpressがハンドリングしてくれなかった。
以下がreject側のコード。
TypeScriptです。
public static signup(userName: string, userPassword: string): Promise<User> {
return new Promise<User>( (resolve, reject) => {
const db1Master: DbMasterConnection = DbConnector.createInstance().createMaster(DbType.DB1);
UserRepo.findByName(userName, db1Master).then( (user: User) => {
if(user.isEmpty() === false){
//ユーザーが存在しているので例外
reject(AppException.createError(AppErrorRegistry.DB_CONNECTION_ERROR));
}else{
//とりあえず resolve
resolve(Promise.resolve(new User(100000, 'test', 'test', new RecordTime())));
}
});
});
}
以下がcatch側のコード。
router.post('/add', function(req, res, next) {
LoginApplication.signup(req.body.user_name, req.body.user_password).then( (user: User) => {
//正常処理
res.redirect('/');
}).catch( (err) => {
//エラー
throw err;
});
});
catch() 内の throw err でExpressのエラーハンドリングに拾われると思ったけど、
拾われなかった。
問題はcatch側のコードにあった。
修正したものが以下。
router.post('/add', function(req, res, next) {
LoginApplication.signup(req.body.user_name, req.body.user_password).then( (user: User) => {
//正常処理
res.redirect('/');
}).catch( (err) => {
//エラー
next(err);
});
});catch内の next(err) が修正箇所。
ドキュメントの http://expressjs.com/guide/routing.html の Route handlers を確認したところ、
Expressの next() は処理を他のミドルウェアに委譲する関数らしい。
で、エラーハンドリングは app.js で以下のように設定されている。
app.use(function(err: any, req, res, next) {
res.status(err['status'] || 500);
res.render('error', {
message: err.message,
error: err
});
});多分、このエラーハンドリングがrouterのnext()で呼ばれるんだと思う。