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

Aks*_*Aks 3 custom-errors custom-error-handling hapi joi

我有两个文件,一个是 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;
Run Code Online (Sandbox Code Playgroud)

通过这个,如果发生错误,那么我得到了这样的响应

{"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}
Run Code Online (Sandbox Code Playgroud)

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

Gee*_* VB 6

TL;DR:创建您自己的“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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

您显然可以更改上述内容以满足您的需求。


更新

Celebrate 将其错误结构更改为 CelebrateError,现在您需要使用以下方法访问错误详细信息:

  const errorBody = err.details.get('body'); // 'details' is a Map()
  const { details: [errorDetails] } = errorBody;
Run Code Online (Sandbox Code Playgroud)

而不是err.joi. 消息属性保持不变。


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