You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js使用Joi做参数校验未触发预期报错的问题排查

问题定位

核心错误出在validateRequest.js中间件的返回值解构逻辑:Joi 官方标准包的validate()方法执行后,返回的对象中校验错误对应的属性名是**error**,你代码里写的是解构err,导致实际拿到的err永远是undefined,错误判断分支永远不会触发,无论请求体是否符合校验规则,都会直接走next()放行到后续业务处理逻辑,自然不会抛出校验错误。

额外提示:你代码里打印validateDataRepo['$_root']属于调试残留,上线前可以删掉,不影响功能但无保留必要。另外要确认Express入口文件已经配置了app.use(express.json()),否则POST请求的JSON请求体不会被正确解析到req.body上。

修复方案

只需要修改中间件里解构返回值、判断错误的两行代码即可,修复后的完整中间件代码如下:

const Joi = require('joi');

module.exports.validateRequest = (schema) => {
    return (req, res, next) => {
        const options = {
            abortEarly: false, // 收集所有校验错误,不遇到第一个错误就终止
            allowUnknown: true, // 允许请求体携带schema未定义的字段
            stripUnknown: true // 校验通过后,自动剥离请求体里未在schema中定义的字段
        };

        // 修正:解构error字段,而非err
        const { error, value } = schema.validate(req.body, options);

        if (error) {
            next(`Validation error: ${error.details.map(x => x.message).join(', ')}`);
        } else {
            req.body = value;
            next();
        }
    };
};
验证效果

修复后重新发起带请求体{ "ownerId": "t" }的POST请求,会正常抛出校验错误,包含两个不符合规则的提示:

  • ownerId 长度小于要求的最小长度5
  • 必填字段uri缺失

另外你的Schema定义写法没有问题,Joi.object().keys({...})和简写的Joi.object({...})效果完全一致,不需要额外修改。


内容的提问来源于stack exchange,提问作者Sam T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 03:33:33