如何管理自行创建的错误消息,而不是使用默认的庆祝@ hapi / joi代码

时间:2019-05-02 14:13:09

标签: joi custom-errors hapi custom-error-handling

我有两个文件,一个是api.js,另一个是handler.js。对于模式处理,我使用了庆祝模块@ hapi / joi

  

在api.js上,我只写了API名称

     

在handler.js上,我编写了API功能。

api.js
//JOI Schema Validator Middleware.
router.use(celebrate({
    body: Joi.object().keys({
        post: Joi.string().max(10),
        userid: Joi.string(),
    })
}));

const handler = require('./handler');

router.post('/createpost', handler.createPost);

router.use(errors());

module.exports = router;

如果发生错误,我会得到这样的响应

{"statusCode":400,"error":"Bad Request","message":"child \"post\" fails because [\"post\" length must be less than or equal to 10 characters long]","validation":{"source":"body","keys":["post"]}}

我只想将此错误转换为我自己的格式错误,即类似这样的

{error: true, status: 500, message: 'validation error', version: x.x.2}

默认的joi错误是通过router.use(errors());这个模块生成的。我该如何修改? 任何帮助或建议都非常感谢。

2 个答案:

答案 0 :(得分:0)

TL; DR:创建自己的“ errors()”函数。

您现在可能已经设法进行了更改,但是就像我一样,我遇到了完全相同的问题,并发现了这个无答案的线程。

好吧,对于将来的读者来说,庆祝errors()就是一个函数,更确切地说,就是这个函数:

(err, req, res, next) => {
  // If this isn't a Celebrate error, send it to the next error handler
  if (!isCelebrate(err)) {
    return next(err);
  }

  const {
    joi,
    meta,
  } = err;

  const result = {
    statusCode: 400,
    error: 'Bad Request',
    message: joi.message,
    validation: {
      source: meta.source,
      keys: [],
    },
  };

  if (joi.details) {
    for (let i = 0; i < joi.details.length; i += 1) {
      const path = joi.details[i].path.join('.');
      result.validation.keys.push(EscapeHtml(path));
    }
  }
  return res.status(400).send(result);
}

在那里,您可以看到已声明响应对象“结果”及其完成方式。因此,要更改其输出,您必须不使用 errors(),并创建自己的函数来处理它。

所以,我声明了一个新函数:

  private errorHandling = (err, req, res, next) => {
    if (isCelebrate(err)) {
        return res.send({
            statusCode: 400,
            message: err.joi.message
        });
    }

    return next(err);
  }

您显然可以根据需要更改以上内容。

然后,我使用app.use(errors())而不是使用app.use(this.errorHandling),现在我得到了希望的格式化的庆祝响应。

答案 1 :(得分:0)

经过研究,我发现可以通过两种方法解决该问题:

[Segments.BODY]: Joi.object().keys({
value: Joi.string().required().error(new Error('Value is required and has to be a text!')),
})

[Segments.BODY]: Joi.object().keys({
password: Joi.string().required().pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')).min(8).label('Password').messages({
    'string.pattern.base': 'Your {#label} does not matche the suggested pattern',
    'string.base': `Your {#label} should match the suggested pattern`,
    'string.empty': `Your {#label} can not be empty`,
    'string.min': `Your {#label} has to be at least {#limit} chars`,
    'any.required': `Your {#label} is required`,
}),

})