首页 > 解决方案 > 尽管将 abort early false 设置为 JOI 验证并没有返回所有错误

问题描述

我一直在尝试通过 joi 模式验证我的有效负载。但它并没有返回我在模式中编写的错误,而是只显示一个错误。即使我给像 name=int 这样的有效负载,尽管给第二个输入(即用户名)一个整数值,但只显示一个自定义错误:

{“状态代码”:400,

"error": "错误请求",

“消息”:“名称需要一个字符串”}

而是应该打印

{“状态代码”:400,

"error": "错误请求",

"message": "name 需要一个字符串"/"username 需要一个字符串" }

这是我的代码:server.js

    const server = Hapi.server({
        port: 3000,
        routes: {
            validate: {
                options: {
                    abortEarly: false
                  },
                failAction: async (request, response, err) => {
                    throw Boom.badRequest(err.message);
                },
            },

        },
    });

joi-schmea.js

const NamePayload = Joi.object().keys({
    name: Joi.string().required().error(new Error('name expecting a string')),
    username: Joi.string().required().error(new Error('username expecting a string')),
    age: Joi.integer().required().error(new Error('age expecting a number')),

});

路线.js:

validate: {
        payload: Schema.NamePayload,

      },

我希望邮递员不仅显示第一条错误消息,还显示所有错误消息。而且我也不想使用默认错误消息child must be string/int类型错误,这就是我使用新错误的原因。我已阅读有关该错误的所有 stackoverflow 文章,但没有解决我的问题。这是我使用的 hapi 和 joi 版本:

@hapi/joi:^15.0.3,

@hapi/hapi:^18.3.1,

标签: javascriptnode.jshapijsjoi

解决方案


据我了解,每个 Joi 错误都会引发一个ValidationError包含关键细节的错误,这是一个错误数组,除其他外,每个错误都有您的自定义错误消息,并且通过在您的架构中执行new Error()您正在覆盖它关键细节。所以,我建议你这样做:

将您的架构错误替换为:

Joi.object().keys({
    name: Joi.string().required().error(() => 'name expecting a string'),
    username: Joi.string().required().error(() => 'username expecting a string'),
    age: Joi.number().integer().required().error(() => 'age expecting a number'),
});

然后在您的failAction中连接err.details中的那些消息:

failAction: async (request, response, err) => {
    throw Boom.badRequest(err.details.map((error) => error.message).join('/'));
}

对于此有效负载:

{
   "name": 10
}

你会得到这样的回应:

{
   "statusCode": 400,
   "error": "Bad Request",
   "message": "name expecting a string/username expecting a string/age expecting a number"
}

推荐阅读