localhost
GET
¥Error Handling
本页提供更高级的指南,帮助你有效地使用 Elysia 处理错误。
¥This page provide a more advance guide for effectively handling errors with Elysia.
如果你还没有阅读 "生命周期 (onError)",我们建议你先阅读它。
¥If you haven't read "Life Cycle (onError)" yet, we recommend you to read it first.
¥Custom Validation Message
定义架构时,可以为每个字段提供自定义验证消息。
¥When defining a schema, you can provide a custom validation message for each field.
当验证失败时,此消息将按原样返回。
¥This message will be returned as-is when the validation fails.
import { Elysia } from 'elysia'
new Elysia().get('/:id', ({ params: { id } }) => id, {
params: t.Object({
id: t.Number({
error: 'id must be a number'
})
})
})
如果 id
字段验证失败,则返回结果为 id must be a number
。
¥If the validation fails on the id
field, the response will be return as id must be a number
.
GET
¥Validation Detail
从 schema.error
返回值将按原样返回验证,但有时你可能还希望返回验证详细信息,例如字段名称和预期类型。
¥Returning as 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
选项执行此操作。
¥You can do this by using the validationDetail
option.
import { Elysia, validationDetail } from 'elysia'
new Elysia().get('/:id', ({ params: { id } }) => id, {
params: t.Object({
id: t.Number({
error: validationDetail('id must be a number')
})
})
})
这将在响应中包含所有验证详细信息,例如字段名称和预期类型。
¥This will include all of the validation details in the response, such as the field name and the expected type.
GET
但如果你计划在每个字段中使用 validationDetail
,手动添加它会很麻烦。
¥But if you're planned to use validationDetail
in every field, adding it manually can be annoying.
你可以通过在 onError
钩子中处理来自动添加验证详细信息。
¥You can automatically add validation detail by handling it in onError
hook.
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 must be a number'
})
})
})
.listen(3000)
这将为每个验证错误应用自定义验证消息。
¥This will apply every validation error with a custom message with custom validation message.
¥Validation Detail on production
默认情况下,如果 NODE_ENV
是 production
,Elysia 将省略所有验证细节。
¥By default, Elysia will omitted all validation detail if NODE_ENV
is production
.
这样做是为了防止泄露有关验证模式的敏感信息,例如字段名称和预期类型,这些信息可能被攻击者利用。
¥This is done to prevent leaking sensitive information about the validation schema, such as field names and expected types, which could be exploited by an attacker.
Elysia 将仅返回验证失败,不提供任何详细信息。
¥Elysia will only return that validation failed without any details.
{
"type": "validation",
"on": "body",
"found": {},
// Only shown for custom error
"message": "x must be a number"
}
message
属性是可选的,默认情况下会省略,除非你在架构中提供自定义错误消息。
¥The message
property is optional and is omitted by default unless you provide a custom error message in the schema.
¥Custom Error
Elysia 在类型级别和实现级别都支持自定义错误。
¥Elysia supports custom error both in the type-level and implementation level.
默认情况下,Elysia 具有一组内置错误类型,例如 VALIDATION
、NOT_FOUND
,它们会自动缩小类型范围。
¥By default, Elysia have a set of built-in error types like VALIDATION
, NOT_FOUND
which will narrow down the type automatically.
如果 Elysia 不知道错误,错误代码将为 UNKNOWN
,默认状态为 500
。
¥If Elysia doesn't know the error, the error code will be UNKNOWN
with default status of 500
但是,你也可以使用 Elysia.error
添加具有类型安全性的自定义错误,这将有助于缩小错误类型范围,从而实现完全类型安全性和自动补齐功能,并自定义状态代码,如下所示:
¥But you can also add a custom error with type safety with Elysia.error
which will help narrow down the error type for full type safety with auto-complete, and custom status code as follows:
import { Elysia } from 'elysia'
class MyError extends Error {
constructor(public message: string) {
super(message)
}
}
new Elysia()
.error({
MyError
})
.onError(({ code, error }) => {
switch (code) {
// With auto-completion
case 'MyError':
// With type narrowing
// Hover to see error is typed as `CustomError`
return error
}
})
.get('/:id', () => {
throw new MyError('Hello Error')
})
¥Custom Status Code
你还可以通过在自定义错误类中添加 status
属性,为自定义错误提供自定义状态代码。
¥You can also provide a custom status code for your custom error by adding status
property in your custom error class.
import { Elysia } from 'elysia'
class MyError extends Error {
status = 418
constructor(public message: string) {
super(message)
}
}
Elysia 将在抛出错误时使用此状态码。
¥Elysia will then use this status code when the error is thrown.
或者,你也可以在 onError
钩子中手动设置状态码。
¥Otherwise you can also set the status code manually in the onError
hook.
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')
})
¥Custom Error Response
你还可以在自定义错误类中提供自定义 toResponse
方法,以便在抛出错误时返回自定义响应。
¥You can also provide a custom toResponse
method in your custom error class to return a custom response when the error is thrown.
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
})
}
}
¥To Throw or Return
Elysia 中的大多数错误处理可以通过抛出错误来完成,并将在 onError
中处理。
¥Most of an error handling in Elysia can be done by throwing an error and will be handle in onError
.
但 status
可能会有点令人困惑,因为它既可以用作返回值,也可以抛出错误。
¥But for status
it can be a little bit confusing, since it can be used both as a return value or throw an error.
它可以根据你的具体需求返回或抛出异常。
¥It could either be return or throw based on your specific needs.
如果抛出 status
异常,它将被 onError
中间件捕获。
如果返回的是 status
,它将不会被 onError
中间件捕获。
参见以下代码:
¥See the following code:
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)
})
GET