Node.js错误处理设置未按预期工作

时间:2019-05-22 20:15:31

标签: javascript node.js error-handling

我试图将所有错误消息保存在一个文件中,每个错误都用一个错误代码表示,然后在我的函数/服务中,当出现错误时,我调用一个以错误代码为参数的函数,然后将错误代码和来自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
    })
}

errors.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);
...

现在使用此设置,当邮递员到达注册端点时,我只能在控制台中获得以下信息

  

UnhandledPromiseRejection警告:错误:用户已注册

有人可以告诉我我在这里想念什么吗? 预先感谢!

1 个答案:

答案 0 :(得分:1)

您没有发现errorThrower内抛出的错误,因此得到了错误UnhandledPromiseRejectionWarning。您需要做的就是捕获错误,然后将其传递给下一个中间件,以使errorHandler-中间件能够实际处理该错误。像这样:

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));