繁体   English   中英

Joi 验证错误来自哪个字段在 UI 中显示错误

[英]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
   }
}

现在在上面发布在问题中的代码中使用这个类。 使用 ValidationError 而不是 Error 类,并将字段名称传递给它。 例子

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'))
})

记住在使用自定义类时使用new 验证的代码可以从传递下来的错误对象中获取error.fieldName值。

我希望这是正确的方法。 如果有更好的方法,请张贴我会接受它作为答案。

我认为有更好的方法来实现这一点,因为不推荐使用抛出错误来实现这一点。 ( 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的属性,您可以从中访问有关这些错误的详细信息(例如这些错误属于哪些字段)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM