Node.js + Joi 如何显示自定义错误信息?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48720942/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Node.js + Joi how to display a custom error messages?
提问by Raz
It seems pretty straight forward to validate user's input in Node.js RESTapi with Joi.
在 Node.js RESTapi 中使用Joi.
But the problem is that my app is not written in English. That means I need to send a custom written messages to the frontend user.
但问题是我的应用程序不是用英文编写的。这意味着我需要向前端用户发送自定义的书面消息。
I have googled for this and only found issues.
我用谷歌搜索过这个,只发现了问题。
Maybe could someone give a solution for this?
也许有人可以为此提供解决方案?
This is the code I am using to validate with the Joisystem:
这是我用来验证Joi系统的代码:
var schema = Joi.object().keys({
firstName: Joi.string().min(5).max(10).required(),
lastName: Joi.string().min(5).max(10).required()
..
});
Joi.validate(req.body, schema, function(err, value) {
if (err) {
return catched(err.details);
}
});
function catched(reject) {
res.json({
validData: false,
errors: reject
});
}
Plus, is there a way to use Joiin client side?
另外,有没有办法Joi在客户端使用?
Thanks!
谢谢!
采纳答案by Raz
A solution I have found is to set:
我发现的一个解决方案是设置:
var schema = Joi.object().keys({
firstName: Joi.string().min(5).max(10).required().label("Your error message in here"),
lastName: Joi.string().min(5).max(10).required()
..
});
Then print the labelfrom the callback errorvariable
然后label从回调error变量打印
回答by Ashish Kadam
Joi Version 14.0.0
Joi 版本 14.0.0
const SchemaValidation = {
coins: Joi.number()
.required()
.error(() => {
return {
message: 'Coins is required.',
};
}),
challenge_name: Joi.string()
.required()
.error(() => {
return {
message: 'Challenge name is required.',
};
}),
challengeType: Joi.string()
.required()
.error(() => {
return {
message: 'Challenge type is required.',
};
}),
challengeDescription: Joi.string()
.required()
.error(() => {
return {
message: 'Challenge description is required.',
};
}),
};
In errorsobject you can get, error type and change message according.
在错误对象中,您可以获得错误类型和更改消息。
回答by Guillermo Gutiérrez
Extending on Ashish Kadam's answer, if you have many different error types, you can check which type of error is present, and set its message accordingly:
扩展Ashish Kadam 的回答,如果您有许多不同的错误类型,您可以检查存在哪种类型的错误,并相应地设置其消息:
var schema = Joi.object().keys({
firstName: Joi.string().min(5).max(10).required().error(errors => {
errors.forEach(err => {
switch (err.type) {
case "any.empty":
err.message = "Value should not be empty!";
break;
case "string.min":
err.message = `Value should have at least ${err.context.limit} characters!`;
break;
case "string.max":
err.message = `Value should have at most ${err.context.limit} characters!`;
break;
default:
break;
}
});
return errors;
}),
// ...
});
You can check the list of errors here: Joi 14.3.1 API Reference > Errors > List of errors
您可以在此处查看错误列表:Joi 14.3.1 API 参考 > 错误 > 错误列表
Also you can check the any.errorreference for more information. Quoting the docs:
您也可以查看any.error参考资料以获取更多信息。引用文档:
Overrides the default joi error with a custom error if the rule fails where:
errcan be:
- an instance of
Error- the override error.- a
function(errors), taking an array of errors as argument, where it must either:
- return a
string- substitutes the error message with this text- return a single
objector anArrayof it, where:
type- optional parameter providing the type of the error (eg.number.min).message- optional parameter iftemplateis provided, containing the text of the error.template- optional parameter ifmessageis provided, containing a template string, using the same format as usual joi language errors.context- optional parameter, to provide context to your error if you are using thetemplate.- return an
Error- same as when you directly provide anError, but you can customize the error message based on the errors.options:
self- Boolean value indicating whether the error handler should be used for all errors or only for errors occurring on this property (truevalue). This concept only makes sense forarrayorobjectschemas as other values don't have children. Defaults tofalse.
如果规则失败,则使用自定义错误覆盖默认的 joi 错误,其中:
err可:
Error- 覆盖错误的一个实例。- a
function(errors),将一系列错误作为参数,它必须:
- return a
string- 用此文本替换错误消息- 返回单个
object或其中一个Array,其中:
type- 提供错误类型的可选参数(例如。number.min)。message- 如果template提供了可选参数,包含错误文本。template- 提供了可选参数 ifmessage,包含模板字符串,使用与通常的 joi 语言错误相同的格式。context- 可选参数,如果您使用template.- 返回
Error- 与直接提供时相同Error,但您可以根据错误自定义错误消息。options:
self- 布尔值,指示错误处理程序应用于所有错误还是仅用于此属性上发生的错误(true值)。这个概念只对arrayorobject模式有意义,因为其他值没有孩子。默认为false.
回答by Rvy Pandey
Edit:
编辑:
Make sure you are using @hapi/joi- https://www.npmjs.com/package/@hapi/joi, version 16 and above.
确保您使用的是 -https @hapi/joi: //www.npmjs.com/package/@hapi/joi,版本 16 及更高版本。
Original answer:
原答案:
The current way (I personally find it better) is to use .messages()(or .prefs({messages})).
目前的方法(我个人觉得它更好)是使用.messages()(或.prefs({messages}))。
const Joi = require('@hapi/joi');
const joiSchema = Joi.object({
a: Joi.string()
.min(2)
.max(10)
.required()
.messages({
'string.base': `"a" should be a type of 'text'`,
'string.empty': `"a" cannot be an empty field`,
'string.min': `"a" should have a minimum length of {#limit}`,
'any.required': `"a" is a required field`
})
});
const validationResult = joiSchema.validate({ a: 2 }, { abortEarly: false });
console.log(validationResult.error); // expecting ValidationError: "a" should be a type of 'text'
Usage of .errors()is not recommendedjust to update default message with custom message.
的使用.errors()是不建议只是使用定制信息更新默认消息。
.prefs({ messages })is an elaborate way to provide more options as preferences. The other options for prefs are taken directly from options of .validate()
.prefs({ messages })是一种提供更多选项作为首选项的精心设计的方法。prefs 的其他选项直接取自.validate() 的选项
Further read: https://github.com/hapijs/joi/issues/2158
进一步阅读:https: //github.com/hapijs/joi/issues/2158
Update 1: I saw that the above explanation did not work out for some folks, so I have put up some code to test yourself. Check it here: https://runkit.com/embed/fnfaq3j0z9l2
更新 1:我看到上面的解释对某些人不起作用,所以我放了一些代码来测试自己。在这里检查:https: //runkit.com/embed/fnfaq3j0z9l2
Also updated the code snippet shared previously to have details from package inclusion, to usage, to calling the actual validation method.
还更新了之前共享的代码片段,以包含从包包含、使用到调用实际验证方法的详细信息。
Update 2: The list of joi error types and their description (for .messages()- like string.base, array.unique, date.min etc..) is available here.
更新 2: joi 错误类型列表及其描述(.messages()例如 string.base、array.unique、date.min 等)可在此处获得。
回答by Sameer Ek
You can use .error(new Error('message')), And its work for me
你可以使用.error(new Error('message')),它对我有用
var schema = Joi.object().keys({
firstName: Joi.string().min(5).max(10).required().error(new Error('Give your error message here for first name')),
lastName: Joi.string().min(5).max(10).required().error(new Error('Give your error message here for last name'))
..
});
Joi.validate(req.body, schema, function(err, value) {
if (err) {
console.log(err.message)
return catched(err.message);
}
});
回答by Syeda Aimen Batool
Solution to add custom messages:Simply add another chained function to throw error while defining your schema.
In your case
添加自定义消息的解决方案:只需添加另一个链式函数即可在定义架构时抛出错误。
在你的情况下
firstName: Joi.string().min(5).max(10).required().error(new Error('I am a custom error and I know it!')),
Rest will remain same.
休息将保持不变。
Solution to use Joi at client side(Your 2nd question)
在客户端使用 Joi 的解决方案(您的第二个问题)
Joi-Browseris the package which enables usage of the same schema at the client side.
Joi-Browser是允许在客户端使用相同模式的包。
Hereis an interesting discussion you can have a look at.
这是一个有趣的讨论,你可以看看。
Cheers!
干杯!
回答by Max Sherbakov
回答by Csaba Varga
For anyone having a problem with
对于任何有问题的人
...messages is not a function
...消息不是函数
errors, you must install joiwith npm install @hapi/joi, and importing it with @hapi/joi. I've made the mistake of installing joiwithout the @hapi/prefix and it took me a while to find the error.
错误,您必须安装joi有npm install @hapi/joi,并用其导入@hapi/joi。我犯了joi没有安装@hapi/前缀的错误,我花了一段时间才找到错误。
回答by Chavin Kwas
Just call "message()" function :
只需调用“message()”函数:
firstName: Joi.string().message("Your custom message")
回答by Siddharth Sunchu
The best solution I found was :
我发现的最佳解决方案是:
Create a Middleware for JOI validation
为 JOI 验证创建中间件
Validator.js - You can create your custom error object
Validator.js - 您可以创建自定义错误对象
const Joi = require('Joi');
module.exports = schema => (req, res, next) => {
const result = Joi.validate(req.body, schema);
if (result.error) {
return res.status(422).json({
errorCause: result.error.name,
missingParams: result.error.details[0].path,
message: result.error.details[0].message
});
}
next();
};
In the routes or controller pass this middleware function
在路由或控制器中传递这个中间件功能
const joiValidator = require('../utils/validator'); // Wherever you have declare the validator or middlerware
const userSchema = joi.object().keys({
email : joi.string().email().required(),
password : joi.string().required()
});
routes.routes('/').get(joiValidator(userSchema), (req, res) => {
res.status(200).send('Person Check');
});

