私はこの問題に対処するためにカスタムエラークラスを使ってmiddlewareを使用することをお勧めします。
エラークラスを見てみましょう。このクラスには、カスタムエラーメッセージ、httpステータスコード、およびloggerを使用している場合のlogLevelが含まれています。
module.exports = class ApiCalError extends Error {
constructor (message, status, logLevel) {
// Calling parent constructor of base Error class.
super(message);
// Capturing stack trace, excluding constructor call from it.
Error.captureStackTrace(this, this.constructor);
// Saving class name in the property of our custom error as a shortcut.
this.name = this.constructor.name;
// You can use any additional properties you want.
// I'm going to use preferred HTTP status for this error types.
// `500` is the default value if not specified.
this.status = status || 400;
this.logLevel = logLevel || 'warn';
}
toResponseJSON() {
return {
success: false,
message: this.message
}
}
};
ここでコントローラを見てみましょう。私たちは、このコントローラーからの成功した応答のみを送信し、カスタムエラーをミドルウェアに渡しました。
exports.Login = function(req, res, next) {
const validationResult = validateLoginForm(req.body)
if (!validationResult.success) {
var err = new customError(validationResult.message, 400, 'warn')
return next(err)
} else {
return passport.authenticate('local-login', (err, token, userData) => {
if (err) {
if (err.name == 'IncorrectCredentialsError' || err.name == 'EmailNotVerified') {
var error = new customError(err.message, 400, 'warn')
return next(error)
}
return next(err)
}
return res.json({
success: true,
message: 'You have successfully logged in!',
token,
user: userData
})
})(req, res, next)
}
}
ここで、ロガーとエラーハンドラーのミドルウェアを見てみましょう。ここで、ロガーはAPIのエラーをログに記録し、エラーハンドラに渡します。これらの関数は、app.use()
で使用されます。
// Import library
var Logger = function(logger) {
return function(err, req, res, next) {
var meta = {
path: req.originalUrl,
method: req.method,
'user-agent': req.headers['user-agent'],
origin: req.headers.origin
}
if (err instanceof customError) {
logger.log(err.logLevel, err.message, meta)
return next(err)
} else {
logger.log('error', err.message, meta)
return next(err)
}
}
}
var ErrorHandler = function() {
return function(err, req, res, next) {
if (err instanceof customError) {
return res.status(err.status).json(err.toResponseJSON())
}else{
return res.status(500).json({
success: false,
message: err.message
})
}
}
}
module.exports = {
Logger,
ErrorHandler
}