错误处理器
当你按照 JSON\:API 等预定义规范编写 API 服务时,错误格式化工具很有用。
如果没有错误格式化工具,你必须手动循环错误消息并按照 API 团队遵循的规范重新组织。另外,错误格式化程序公开了一个 API,用于在验证生命周期内收集和构建错误消息(没有任何额外的性能开销)。
使用错误报告器
使用 request.validate
方法执行的验证通过内容协商为给定的 HTTP 请求找到最佳的错误报告器。
但是,你也可以显式定义错误报告器,这会关闭内容协商检查。
validator.validate
和 request.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
方法中引发异常。 - 当感到困惑时,请检查 现有错误报告器 的实现。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。