UI 中哪个字段显示错误的 Joi 验证错误
Joi validation error from which field to show error next to it in UI
我必须使用 Joi 验证库来验证 API 输入并发送输出。
我说创建了一个架构如下:
import Joi from '@hapi/joi'
const eventSchema = Joi.object({
title: Joi.string()
.min(7)
.max(50)
.required()
.error(() => Error('Event title has to be least 7 and max 50 characters.')),
description: Joi.string()
.min(10)
.max(400)
.required()
.error(() => Error('Event description has to be least 10 and max 400 characters.')),
place: Joi.string()
.min(6)
.max(40)
.required()
.error(() => Error('Event place has to be least 6 and max 40 characters.'))
})
export default eventSchema
当我验证它时,我收到了预期的验证错误。这里的问题是我不知道哪个字段真正导致了错误。我想知道这一点,因为我想准确地在导致错误的那个字段旁边显示错误,而不仅仅是在表单顶部显示通用验证消息。
const isValid = eventSchema.validate()
if (isValid.error) {
const fieldNameWhichCauseError = ???
return {
errors: { [fieldNameWhichCauseError]: isValid.error.message }
}
}
// Everything looks good save to db
// ...etc.
上面的代码现在可以知道 fieldNameWhichCauseError = ??? 中的字段名称。有人能帮帮我吗?我还没有看到有人这样做过。我也没有在文档中找到。我有太多的架构和验证,这真的阻碍了我在 UI.
中的适当位置显示错误
我自己想出来了。总有一天它可能会帮助在这里搜索的人。
首先我会创建一个自定义的 ValidationError 对象。
class ValidationError extends Error {
constructor(message, fieldName) {
super(message)
this.fieldName = fieldName
}
}
现在在上述 post 问题中的代码中使用此 class。使用 ValidationError 而不是 Error class 并将字段名称传递给它。例子
const eventSchema = Joi.object({
title: Joi.string()
.min(7)
.max(50)
.required()
.error(() => new ValidationError('Event title has to be least 7 and max 50 characters.', 'title'))
})
记得在使用自定义 class 时使用 new。验证的代码可以从传递下来的错误对象中获取 error.fieldName
值。
我希望这是正确的做法。如果有更好的方法,请post我会接受它作为答案。
我认为有更好的方法来实现这一点,因为抛出错误不是推荐的实现方法。 (https://github.com/hapijs/joi/blob/master/API.md#anyerrorerr)
您应该利用 any.messages
(https://github.com/hapijs/joi/blob/master/API.md#anymessagesmessages) 并添加您的自定义消息。您定义它们的方式,即使用户没有指定任何内容,您也总是会收到相同类型的错误消息。还使用错误覆盖 abortEarly
选项。这意味着您不会收到所有消息,只会收到第一条消息。
使用消息可以这样做
const Joi = require('@hapi/joi');
const eventSchema = Joi.object({
title: Joi.string()
.min(7)
.max(50)
.required()
.messages({
'string.base': `"description" should be a type of 'text'`,
'string.min': '"title" has to be least {#limit} characters.',
'string.max': '"title" has to be max {#limit} characters.',
'any.required': `"title" is a required field`,
}),
description: Joi.string()
.min(10)
.max(400)
.required()
.messages({
'string.base': `"description" should be a type of 'text'`,
'string.min': '"description" has to be least {#limit} characters.',
'string.max': '"description" has to be max {#limit} characters.',
'any.required': `"description" is a required field`
}),
place: Joi.string()
.min(6)
.max(40)
.required()
.messages({
'string.base': `"place" should be a type of 'text'`,
'string.min': '"place" has to be least {#limit} characters.',
'string.max': '"place" has to be max {#limit} characters.',
'any.required': `"place" is a required field`
})
});
eventSchema.validate({
"title": "hi"
}, {
"abortEarly": false
});
在 Joi 17.4 上,validate() 返回的 error
有一个名为 details
的 属性,您可以从中访问有关这些错误的详细信息(例如这些错误属于哪些字段)。
我必须使用 Joi 验证库来验证 API 输入并发送输出。
我说创建了一个架构如下:
import Joi from '@hapi/joi'
const eventSchema = Joi.object({
title: Joi.string()
.min(7)
.max(50)
.required()
.error(() => Error('Event title has to be least 7 and max 50 characters.')),
description: Joi.string()
.min(10)
.max(400)
.required()
.error(() => Error('Event description has to be least 10 and max 400 characters.')),
place: Joi.string()
.min(6)
.max(40)
.required()
.error(() => Error('Event place has to be least 6 and max 40 characters.'))
})
export default eventSchema
当我验证它时,我收到了预期的验证错误。这里的问题是我不知道哪个字段真正导致了错误。我想知道这一点,因为我想准确地在导致错误的那个字段旁边显示错误,而不仅仅是在表单顶部显示通用验证消息。
const isValid = eventSchema.validate()
if (isValid.error) {
const fieldNameWhichCauseError = ???
return {
errors: { [fieldNameWhichCauseError]: isValid.error.message }
}
}
// Everything looks good save to db
// ...etc.
上面的代码现在可以知道 fieldNameWhichCauseError = ??? 中的字段名称。有人能帮帮我吗?我还没有看到有人这样做过。我也没有在文档中找到。我有太多的架构和验证,这真的阻碍了我在 UI.
中的适当位置显示错误我自己想出来了。总有一天它可能会帮助在这里搜索的人。
首先我会创建一个自定义的 ValidationError 对象。
class ValidationError extends Error {
constructor(message, fieldName) {
super(message)
this.fieldName = fieldName
}
}
现在在上述 post 问题中的代码中使用此 class。使用 ValidationError 而不是 Error class 并将字段名称传递给它。例子
const eventSchema = Joi.object({
title: Joi.string()
.min(7)
.max(50)
.required()
.error(() => new ValidationError('Event title has to be least 7 and max 50 characters.', 'title'))
})
记得在使用自定义 class 时使用 new。验证的代码可以从传递下来的错误对象中获取 error.fieldName
值。
我希望这是正确的做法。如果有更好的方法,请post我会接受它作为答案。
我认为有更好的方法来实现这一点,因为抛出错误不是推荐的实现方法。 (https://github.com/hapijs/joi/blob/master/API.md#anyerrorerr)
您应该利用 any.messages
(https://github.com/hapijs/joi/blob/master/API.md#anymessagesmessages) 并添加您的自定义消息。您定义它们的方式,即使用户没有指定任何内容,您也总是会收到相同类型的错误消息。还使用错误覆盖 abortEarly
选项。这意味着您不会收到所有消息,只会收到第一条消息。
使用消息可以这样做
const Joi = require('@hapi/joi');
const eventSchema = Joi.object({
title: Joi.string()
.min(7)
.max(50)
.required()
.messages({
'string.base': `"description" should be a type of 'text'`,
'string.min': '"title" has to be least {#limit} characters.',
'string.max': '"title" has to be max {#limit} characters.',
'any.required': `"title" is a required field`,
}),
description: Joi.string()
.min(10)
.max(400)
.required()
.messages({
'string.base': `"description" should be a type of 'text'`,
'string.min': '"description" has to be least {#limit} characters.',
'string.max': '"description" has to be max {#limit} characters.',
'any.required': `"description" is a required field`
}),
place: Joi.string()
.min(6)
.max(40)
.required()
.messages({
'string.base': `"place" should be a type of 'text'`,
'string.min': '"place" has to be least {#limit} characters.',
'string.max': '"place" has to be max {#limit} characters.',
'any.required': `"place" is a required field`
})
});
eventSchema.validate({
"title": "hi"
}, {
"abortEarly": false
});
在 Joi 17.4 上,validate() 返回的 error
有一个名为 details
的 属性,您可以从中访问有关这些错误的详细信息(例如这些错误属于哪些字段)。