错误
错误
¥Errors
目录
¥Table of contents
Node.js 中的错误处理
¥Error Handling In Node.js
未捕获的错误
¥Uncaught Errors
在 Node.js 中,未捕获的错误可能会导致内存泄漏、文件描述符泄漏和其他主要生产问题。Domains 是修复此问题的失败尝试。
¥In Node.js, uncaught errors are likely to cause memory leaks, file descriptor leaks, and other major production issues. Domains were a failed attempt to fix this.
鉴于不可能合理地处理所有未捕获的错误,处理它们的最佳方法是 crash。
¥Given that it is not possible to process all uncaught errors sensibly, the best way to deal with them is to crash.
捕获 Promise 中的错误
¥Catching Errors In Promises
如果你正在使用 promise,则应同步附加 .catch()
处理程序。
¥If you are using promises, you should attach a .catch()
handler synchronously.
Fastify 中的错误
¥Errors In Fastify
Fastify 遵循“全有或全无”的方法,旨在尽可能精简和优化。开发者有责任确保正确处理错误。
¥Fastify follows an all-or-nothing approach and aims to be lean and optimal as much as possible. The developer is responsible for making sure that the errors are handled properly.
输入数据错误
¥Errors In Input Data
大多数错误都是由于意外输入数据造成的,因此我们推荐 根据 JSON 模式验证你的输入数据。
¥Most errors are a result of unexpected input data, so we recommend validating your input data against a JSON schema.
在 Fastify 中捕获未捕获的错误
¥Catching Uncaught Errors In Fastify
Fastify 尝试在不影响性能的情况下捕获尽可能多的未捕获错误。这包括:
¥Fastify tries to catch as many uncaught errors as it can without hindering performance. This includes:
同步路由,例如
app.get('/', () => { throw new Error('kaboom') })
¥synchronous routes, e.g.
app.get('/', () => { throw new Error('kaboom') })
async
路由,例如app.get('/', async () => { throw new Error('kaboom') })
¥
async
routes, e.g.app.get('/', async () => { throw new Error('kaboom') })
两种情况下的错误都将被安全捕获并路由到 Fastify 的默认错误处理程序以获得通用 500 Internal Server Error
响应。
¥The error in both cases will be caught safely and routed to Fastify's default
error handler for a generic 500 Internal Server Error
response.
要自定义此行为,你应该使用 setErrorHandler
。
¥To customize this behavior you should use
setErrorHandler
.
Fastify 生命周期钩子和自定义错误处理程序中的错误
¥Errors In Fastify Lifecycle Hooks And A Custom Error Handler
从 钩子文档:
¥From the Hooks documentation:
如果在执行钩子时出现错误,只需将其传递给
done()
,Fastify 就会自动关闭请求并向用户发送相应的错误代码。¥If you get an error during the execution of your hook, just pass it to
done()
and Fastify will automatically close the request and send the appropriate error code to the user.
当通过 setErrorHandler
定义自定义错误处理程序时,自定义错误处理程序将接收传递给 done()
回调的错误(或通过其他受支持的自动错误处理机制)。如果 setErrorHandler
已被多次用于定义多个处理程序,则错误将被路由到错误 封装上下文 中定义的最先的处理程序。错误处理程序是完全封装的,因此插件内的 setErrorHandler
调用将限制错误处理程序到该插件的上下文。
¥When a custom error handler has been defined through
setErrorHandler
, the custom error handler will
receive the error passed to the done()
callback (or through other supported
automatic error handling mechanisms). If setErrorHandler
has been used
multiple times to define multiple handlers, the error will be routed to the most
precedent handler defined within the error encapsulation
context. Error handlers are fully encapsulated, so a
setErrorHandler
call within a plugin will limit the error handler to that
plugin's context.
根错误处理程序是 Fastify 的通用错误处理程序。如果存在,此错误处理程序将使用 Error
对象中的标头和状态代码。如果提供了自定义错误处理程序,则不会自动设置标头和状态代码。
¥The root error handler is Fastify's generic error handler. This error handler
will use the headers and status code in the Error
object, if they exist. The
headers and status code will not be automatically set if a custom error handler
is provided.
在自定义错误处理程序中需要考虑的一些事项:
¥Some things to consider in your custom error handler:
你可以使用
reply.send(data)
,其行为将与在 常规路由处理程序 中一样¥you can
reply.send(data)
, which will behave as it would in regular route handlers对象被序列化,触发
preSerialization
生命周期钩子(如果你定义了一个)¥objects are serialized, triggering the
preSerialization
lifecycle hook if you have one defined字符串、缓冲区和流被发送到客户端,并带有适当的标头(无序列化)
¥strings, buffers, and streams are sent to the client, with appropriate headers (no serialization)
你可以在自定义错误处理程序中抛出新错误 - 错误(新错误或重新抛出收到的错误参数) - 将调用父
errorHandler
。¥You can throw a new error in your custom error handler - errors (new error or the received error parameter re-thrown) - will call the parent
errorHandler
.onError
钩子只会在第一次抛出错误时触发一次。¥
onError
hook will be triggered once only for the first error being thrown.生命周期钩子不会两次触发错误 - Fastify 内部监控错误调用,以避免在生命周期的回复阶段抛出错误而导致无限循环。(路由处理程序之后的那些)
¥an error will not be triggered twice from a lifecycle hook - Fastify internally monitors the error invocation to avoid infinite loops for errors thrown in the reply phases of the lifecycle. (those after the route handler)
当通过 setErrorHandler
使用 Fastify 的自定义错误处理时,你应该了解错误如何在自定义和默认错误处理程序之间传播。
¥When utilizing Fastify's custom error handling through setErrorHandler
,
you should be aware of how errors are propagated between custom and default
error handlers.
如果插件的错误处理程序重新抛出错误,并且该错误不是 错误 的实例(如下例中的 /bad
路由所示),则它不会传播到父上下文错误处理程序。相反,它将被默认错误处理程序捕获。
¥If a plugin's error handler re-throws an error, and the error is not an
instance of Error
(as seen in the /bad
route in the following example), it will not propagate
to the parent context error handler. Instead, it will be caught by the default
error handler.
为确保一致的错误处理,建议抛出 Error
的实例。例如,在下面的例子中,在 /bad
路由中将 throw 'foo'
替换为 throw new Error('foo')
可确保错误按预期通过自定义错误处理链传播。这种做法有助于避免在 Fastify 中使用自定义错误处理时出现的潜在陷阱。
¥To ensure consistent error handling, it is recommended to throw instances of
Error
. For instance, in the following example, replacing throw 'foo'
with
throw new Error('foo')
in the /bad
route ensures that errors propagate through
the custom error handling chain as intended. This practice helps avoid potential
pitfalls when working with custom error handling in Fastify.
例如:
¥For example:
const Fastify = require('fastify')
// Instantiate the framework
const fastify = Fastify({
logger: true
})
// Register parent error handler
fastify.setErrorHandler((error, request, reply) => {
reply.status(500).send({ ok: false })
})
fastify.register((app, options, next) => {
// Register child error handler
fastify.setErrorHandler((error, request, reply) => {
throw error
})
fastify.get('/bad', async () => {
// Throws a non-Error type, 'bar'
throw 'foo'
})
fastify.get('/good', async () => {
// Throws an Error instance, 'bar'
throw new Error('bar')
})
next()
})
// Run the server
fastify.listen({ port: 3000 }, function (err, address) {
if (err) {
fastify.log.error(err)
process.exit(1)
}
// Server is listening at ${address}
})
Fastify 错误代码
¥Fastify Error Codes
你可以访问 errorCodes
进行映射:
¥You can access errorCodes
for mapping:
// ESM
import { errorCodes } from 'fastify'
// CommonJs
const errorCodes = require('fastify').errorCodes
例如:
¥For example:
const Fastify = require('fastify')
// Instantiate the framework
const fastify = Fastify({
logger: true
})
// Declare a route
fastify.get('/', function (request, reply) {
reply.code('bad status code').send({ hello: 'world' })
})
fastify.setErrorHandler(function (error, request, reply) {
if (error instanceof Fastify.errorCodes.FST_ERR_BAD_STATUS_CODE) {
// Log error
this.log.error(error)
// Send error response
reply.status(500).send({ ok: false })
} else {
// fastify will use parent error handler to handle this
reply.send(error)
}
})
// Run the server!
fastify.listen({ port: 3000 }, function (err, address) {
if (err) {
fastify.log.error(err)
process.exit(1)
}
// Server is now listening on ${address}
})
下表列出了 Fastify 使用的所有错误代码。
¥Below is a table with all the error codes that Fastify uses.