javascript - Node.js 错误处理设置未按预期工作
问题描述
我试图将所有错误消息放在一个文件中,每个错误都由错误代码表示,然后在我的函数/服务中,当出现错误时,我调用一个将错误代码作为参数的函数,然后返回带有错误代码和来自errors.js文件的相应错误消息的客户端对象。例如,用户尝试使用数据库中已存在的电子邮件进行注册,这是我尝试的方法:
// userService.js -- where my register function is
const { errorThrower } = require('../../utils/errorHandlers');
...
static async registerNewUser(body) {
const exists = await User.where({ email: body.email }).fetch();
if(exists) {
errorThrower('400_2');
}
...
}
errorHandlers.js 文件:
exports.errorThrower = (errCode) => {
throw Object.assign(new Error(errors[errorCode]), { errorCode })
}
exports.errorHandler = (err, req, res, next) => {
if(!err.status && err.errorCode) {
err.status = parseInt(err.errorCode.toString().substring(0, 3), 10);
}
let status, message
if (err.status) {
status = err.status
message = err.message
} else {
status = 500;
message = 'unexpected behavior, Kindly contact our support team!'
}
res.status(status).json({
errorCode: err.errorCode,
message
})
}
错误.js
module.exports = {
'400_1': 'JSON payload is not valid',
'400_2': 'user already registered',
...
}
...
const user = require('./routes/user');
const { errorHandler } = require('../utils/errors');
...
app.use('/user' , user);
app.use(errorHandler);
...
现在有了这个设置,当邮递员点击注册端点时,我只能在控制台中得到以下内容
UnhandledPromiseRejectionWarning:错误:用户已注册
有人可以告诉我我在这里想念什么吗?提前致谢!
解决方案
你没有捕捉到你抛出的错误errorThrower
,因此得到了错误UnhandledPromiseRejectionWarning
。您需要做的是捕获错误并将其传递给下一个中间件,以便errorHandler
-middleware 能够实际处理错误。像这样的东西:
exports.register = async(req, res) => {
try {
await registerNewUser(req.body);
} catch(err) {
next(err);
}
};
如果您不想为每个中间件都这样做,您可以创建一个“基础”中间件来处理这个问题:
const middlewareExecutor = async (req, res, next, fn) => {
try {
return await fn.call(fn, req, res, next);
} catch (err) {
next(err);
}
};
现在您可以将中间件作为参数传递,并将错误处理委托给执行程序:
app.use('/user' , async (req, res, next) => middlewareExecutor(req, res, next, user));
推荐阅读
- mpdf - 解析使用 GD 库创建的临时文件图像对象以解析 PNG 图像的 PNG 图像时出错
- firebase - 使用颤振(或 Android)的 Firebase 存储规则
- sql - 如何更快地搜索一个有 8000 万条记录的表?
- web - 只需单击恶意/病毒链接,我的 PC 会被黑客入侵吗?(2020 更新)
- html - 如何从 html 按钮添加下载 .app 文件
- ruby-on-rails - 如何防止我的 sidekiq 工作人员超出其数据库连接限制?
- string - 使用 dart 从字符串中获取单词
- spring - 如何修复 Spring Mongo 组聚合中的空值?
- prolog - Prolog 通过给类点数进行分类
- swift - UNUserNotificationCenter.getNotificationSettings 中的计时器失败