localhost
GET
This page provides a more advanced guide for effectively handling errors with Elysia.
如果你还没有阅读 “生命周期 (onError)”,建议先阅读它。
在定义模式时,可以为每个字段提供自定义验证消息。
当验证失败时,该消息将原样返回。
import { Elysia } from 'elysia'
new Elysia().get('/:id', ({ params: { id } }) => id, {
params: t.Object({
id: t.Number({
error: 'id 必须是数字'
})
})
})If the validation fails on the id field, the response will be returned as id must be a number.
GET
Returning a value from schema.error will return the validation as-is, but sometimes you may also want to return the validation details, such as the field name and the expected type
你可以通过使用 validationDetail 来实现这一点。
import { Elysia, validationDetail } from 'elysia'
new Elysia().get('/:id', ({ params: { id } }) => id, {
params: t.Object({
id: t.Number({
error: validationDetail('id 必须是数字')
})
})
})这将在响应中包含所有验证详情,比如字段名和期望类型。
GET
But if you plan to use validationDetail in every field, adding it manually can be annoying.
你可以在 onError 钩子中自动处理验证详情。
new Elysia()
.onError(({ error, code }) => {
if (code === 'VALIDATION') return error.detail(error.message)
})
.get('/:id', ({ params: { id } }) => id, {
params: t.Object({
id: t.Number({
error: 'id 必须是数字'
})
})
})
.listen(3000)这将为每个带有自定义消息的验证错误添加自定义验证详情。
By default, Elysia will omit all validation detail if NODE_ENV is production.
这样做是为了防止泄露验证模式的敏感信息,比如字段名和期望类型,这可能被攻击者利用。
Elysia 只会返回验证失败的信息,而不包含任何详情。
{
"type": "validation",
"on": "body",
"found": {},
// 仅对自定义错误显示
"message": "x 必须是数字"
}message 属性是可选的,默认省略,除非你在模式中提供了自定义错误消息。
可以通过将 Elysia.allowUnsafeValidationDetails 设置为 true 来覆盖此设置,更多详情请参见 Elysia 配置。
Elysia supports custom errors both in the type-level and implementation level.
By default, Elysia has a set of built-in error types like VALIDATION, NOT_FOUND which will narrow down the type automatically.
如果 Elysia 不认识该错误,错误代码将是 UNKNOWN,默认状态码为 500。
但你也可以通过 Elysia.error 添加带类型安全的自定义错误,它能帮助缩小错误类型,提供完整类型安全和自动补全,并支持自定义状态码,如下所示:
import { Elysia } from 'elysia'
class MyError extends Error {
constructor(public message: string) {
super(message)
}
}
new Elysia()
.error({
MyError
})
.onError(({ code, error }) => {
switch (code) {
// 自动补全
case 'MyError':
// 类型缩小
// 悬停查看 error 的类型为 `CustomError`
return error
}
})
.get('/:id', () => {
throw new MyError('Hello Error')
})你也可以通过在自定义错误类中添加 status 属性,为你的自定义错误指定状态码。
import { Elysia } from 'elysia'
class MyError extends Error {
status = 418
constructor(public message: string) {
super(message)
}
}当抛出该错误时,Elysia 会使用此状态码。
否则你也可以在 onError 钩子中手动设置状态码。
import { Elysia } from 'elysia'
class MyError extends Error {
constructor(public message: string) {
super(message)
}
}
new Elysia()
.error({
MyError
})
.onError(({ code, error, status }) => {
switch (code) {
case 'MyError':
return status(418, error.message)
}
})
.get('/:id', () => {
throw new MyError('Hello Error')
})你也可以在自定义错误类中提供一个自定义的 toResponse 方法,当错误被抛出时返回自定义响应。
import { Elysia } from 'elysia'
class MyError extends Error {
status = 418
constructor(public message: string) {
super(message)
}
toResponse() {
return Response.json({
error: this.message,
code: this.status
}, {
status: 418
})
}
}Most error handling in Elysia can be done by throwing an error and will be handled in onError.
但 status 可能会让人困惑,因为它既可以作为返回值也可以抛出错误。
根据你的具体需求,它可以是 返回 或 抛出 。
status 被 抛出,会被 onError 中间件捕获。status 被 返回,不会被 onError 中间件捕获。请看以下代码:
import { Elysia, file } from 'elysia'
new Elysia()
.onError(({ code, error, path }) => {
if (code === 418) return 'caught'
})
.get('/throw', ({ status }) => {
// This will be caught by onError
throw status(418)
})
.get('/return', ({ status }) => {
// This will not be caught by onError
return status(418)
})这里我们使用了 status(418),也就是 “I'm a teapot”(我是茶壶)状态码。你也可以直接使用字符串名称:status("I'm a teapot")。更多关于状态码的使用,请参见 状态码。
GET