错误处理器

未匹配的标注

当你按照 JSON\:API 等预定义规范编写 API 服务时,错误格式化工具很有用。

如果没有错误格式化工具,你必须手动循环错误消息并按照 API 团队遵循的规范重新组织。另外,错误格式化程序公开了一个 API,用于在验证生命周期内收集和构建错误消息(没有任何额外的性能开销)。

使用错误报告器

使用 request.validate 方法执行的验证通过内容协商为给定的 HTTP 请求找到最佳的错误报告器

但是,你也可以显式定义错误报告器,这会关闭内容协商检查。

validator.validaterequest.validate 方法都接受报告器使用,你可以使用其中一个 预先存在的报告器 或创建/使用自定义报告器。

import { schema, validator } from '@ioc:Adonis/Core/Validator'

validator.validate({
  schema: schema.create({}),
  reporter: validator.reporters.api,
})

在验证器类中,你可以将报告器定义为实例属性。

import { schema, validator } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'

export default class CreateUserValidator {
  constructor (protected ctx: HttpContextContract) {}

  public reporter = validator.reporters.api

  public schema = schema.create({
    // ... 架构属性
  })
}

创建你的错误报告器

每个报告器报告都必须依赖 ErrorReporterContract 接口并在其上定义以下属性/方法。

export interface ErrorReporterContract<Messages extends any = any> {
  hasErrors: boolean

  report(
    pointer: string,
    rule: string,
    message: string,
    arrayExpressionPointer?: string,
    args?: any
  ): void

  toError(): any

  toJSON(): Messages
}

report

report 方法在验证失败时由验证器调用,它接收以下参数:

参数 描述
pointer 字段名称的路径,嵌套属性用点表示法表示: user.profile.username
rule 验证规则的名称
message 错误信息
arrayExpressionPointer 当正在验证的当前字段嵌套在数组中时,此属性存在。例如:users.*.username 为数组表达式指针,users.0.pointer为指针
args 失败的验证规则传递的参数

toError

toError 方法必须返回错误类的实例,验证器将抛出此异常。


toJSON

toJSON 方法必须返回验证器迄今为止报告的错误集合。


hasErrors

一个布尔值,用于知道错误报告器到目前为止是否收到任何错误。

创建一个新文件 app/Validators/Reporters/MyReporter.ts 并将以下内容粘贴到其中。


虚拟实现

以下是自定义错误报告器的虚拟实现,你可以进一步调整以满足你的需求。

// 文件名: app/Validators/Reporters/MyReporter.ts
import {
  ValidationException,
  MessagesBagContract,
  ErrorReporterContract,
} from '@ioc:Adonis/Core/Validator'

/**
 * 单个错误的结构
 */
type ErrorNode = {
  message: string,
  field: string,
}

export class MyReporter implements ErrorReporterContract<{ errors: ErrorNode[] }> {
  public hasErrors = false

  /**
   * 跟踪报告的错误
   */
  private errors: ErrorNode[] = []

  constructor (
    private messages: MessagesBagContract,
    private bail: boolean,
  ) {
  }

  /**
   * 验证规则调用以报错
   */
  public report (
    pointer: string,
    rule: string,
    message: string,
    arrayExpressionPointer?: string,
    args?: any
  ) {
    /**
     * 打开标志
     */
    this.hasErrors = true

    /**
     * 使用消息包获取错误信息,消息包会检测用户定义的错误信息,因此必须被使用。
     */
    const errorMessage = this.messages.get(
      pointer,
      rule,
      message,
      arrayExpressionPointer,
      args,
    )

    /**
     * 跟踪错误信息
     */
    this.errors.push({ message: errorMessage, field: pointer })

    /**
     * 保持模式即出现错误便停止验证
     */
    if (this.bail) {
      throw this.toError()
    }
  }

  /**
   * 将验证错误转化为异常
   */
  public toError () {
    throw new ValidationException(false, this.toJSON())
  }

  /**
   * 将错误信息转化为 JSON
   */
  public toJSON () {
    return {
      errors: this.errors,
    }
  }
}

注意事项

  • 你必须始终使用 消息包 来检索错误,它检查用户定义的自定义错误消息并返回给定字段和验证规则的最佳匹配。
  • this.bail 设置为 true 时,你应该始终在 report 方法中引发异常。
  • 当感到困惑时,请检查 现有错误报告器 的实现。

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/adonisjs/5.x/va...

译文地址:https://learnku.com/docs/adonisjs/5.x/va...

上一篇 下一篇
贡献者:1
讨论数量: 0
发起讨论 查看所有版本


暂无话题~