如何让Joi在JSON Schema验证后输出所有带路径的错误信息?
如何让Joi输出所有带字段路径的验证错误
要让Joi输出所有验证错误并包含完整的字段路径,关键要调整Joi的验证配置,同时手动处理错误详情来格式化输出。这里给你两种可行的方案:
方案1:直接使用Joi的validate方法(推荐)
默认情况下Joi的abortEarly选项是true——遇到第一个错误就停止验证。我们需要把它设为false来收集所有错误,然后提取错误详情里的路径和信息进行格式化:
const Joi = require('joi'); // 你的待验证JSON const json = { "myObject": { "myNestedField": { "deepOne": "myValue" } }, "myArray": [ {"field": 1}, {"field": 2}, {"field": 3} ] }; // 定义验证Schema const schema = Joi.object().required().keys({ myObject: Joi.object().required().keys({ myNestedField: Joi.object().required().keys({ deepOne: Joi.string().required().valid("valid") }), myArray: Joi.array().items( Joi.object().keys({ field: Joi.number().required().valid(8) }) ) }) }); // 执行验证,关闭abortEarly以收集所有错误 const { error } = schema.validate(json, { abortEarly: false }); if (error) { // 格式化所有错误信息 const formattedErrors = error.details.map(detail => { // 将路径数组转为点分隔的字符串(如 ['myObject', 'myNestedField', 'deepOne'] → 'myObject.myNestedField.deepOne') const fieldPath = detail.path.join('.'); // 去掉错误消息里的引号,让格式更简洁 const cleanMessage = detail.message.replace(/"/g, ''); return `${fieldPath} - ${cleanMessage}`; }); // 可以抛出包含所有错误的异常,或者直接打印 throw new Error(`Validation failed:\n${formattedErrors.join('\n')}`); } // 验证通过后的逻辑 console.log('All data is valid!');
运行这段代码后,你会得到类似这样的输出:
Error: Validation failed: myObject.myNestedField.deepOne - must be one of [valid] myArray.0.field - must be one of [8] myArray.1.field - must be one of [8] myArray.2.field - must be one of [8]
方案2:结合joi-assert使用
如果你想继续用joi-assert,可以给它传递第三个参数来设置abortEarly: false,然后在catch块里处理错误详情:
const Joi = require('joi'); const joiAssert = require('joi-assert'); const json = { /* 同之前的JSON */ }; const schema = Joi.object().required().keys({ /* 同之前的Schema */ }); try { // 传递验证选项,关闭abortEarly joiAssert(json, schema, { abortEarly: false }); } catch (err) { if (err.details) { // 格式化并输出所有错误 const formattedErrors = err.details.map(detail => { const fieldPath = detail.path.join('.'); const cleanMessage = detail.message.replace(/"/g, ''); return `${fieldPath} - ${cleanMessage}`; }); console.error('Validation errors:\n', formattedErrors.join('\n')); } else { console.error(err.message); } }
关键说明
abortEarly: false是核心:这个配置让Joi不会在遇到第一个错误时就停止,而是收集所有验证失败的信息。error.details数组:每个元素包含了单个错误的完整信息,其中path字段是字段的路径数组,message是错误描述。通过path.join('.')就能得到你想要的点分隔路径格式。
内容的提问来源于stack exchange,提问作者Cherry
相关产品推荐
相关产品推荐

