错误
错误
目录
- 错误
- Node.js 中的错误处理
- Fastify 中的错误
- Fastify 生命周期钩子中的错误和自定义错误处理程序
- Fastify 错误代码
- FST_ERR_NOT_FOUND
- FST_ERR_OPTIONS_NOT_OBJ
- FST_ERR_QSP_NOT_FN
- FST_ERR_SCHEMA_CONTROLLER_BUCKET_OPT_NOT_FN
- FST_ERR_SCHEMA_ERROR_FORMATTER_NOT_FN
- FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_OBJ
- FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_ARR
- FST_ERR_CTP_ALREADY_PRESENT
- FST_ERR_CTP_INVALID_TYPE
- FST_ERR_CTP_EMPTY_TYPE
- FST_ERR_CTP_INVALID_HANDLER
- FST_ERR_CTP_INVALID_PARSE_TYPE
- FST_ERR_CTP_BODY_TOO_LARGE
- FST_ERR_CTP_INVALID_MEDIA_TYPE
- FST_ERR_CTP_INVALID_CONTENT_LENGTH
- FST_ERR_CTP_EMPTY_JSON_BODY
- FST_ERR_CTP_INSTANCE_ALREADY_STARTED
- FST_ERR_INSTANCE_ALREADY_LISTENING
- FST_ERR_DEC_ALREADY_PRESENT
- FST_ERR_DEC_DEPENDENCY_INVALID_TYPE
- FST_ERR_DEC_MISSING_DEPENDENCY
- FST_ERR_DEC_AFTER_START
- FST_ERR_DEC_REFERENCE_TYPE
- FST_ERR_HOOK_INVALID_TYPE
- FST_ERR_HOOK_INVALID_HANDLER
- FST_ERR_HOOK_INVALID_ASYNC_HANDLER
- FST_ERR_HOOK_NOT_SUPPORTED
- FST_ERR_MISSING_MIDDLEWARE
- FST_ERR_HOOK_TIMEOUT
- FST_ERR_LOG_INVALID_DESTINATION
- FST_ERR_LOG_INVALID_LOGGER
- FST_ERR_LOG_INVALID_LOGGER_INSTANCE
- FST_ERR_LOG_INVALID_LOGGER_CONFIG
- FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED
- FST_ERR_REP_INVALID_PAYLOAD_TYPE
- FST_ERR_REP_RESPONSE_BODY_CONSUMED
- FST_ERR_REP_ALREADY_SENT
- FST_ERR_REP_SENT_VALUE
- FST_ERR_SEND_INSIDE_ONERR
- FST_ERR_SEND_UNDEFINED_ERR
- FST_ERR_BAD_STATUS_CODE
- FST_ERR_BAD_TRAILER_NAME
- FST_ERR_BAD_TRAILER_VALUE
- FST_ERR_FAILED_ERROR_SERIALIZATION
- FST_ERR_MISSING_SERIALIZATION_FN
- FST_ERR_MISSING_CONTENTTYPE_SERIALIZATION_FN
- FST_ERR_REQ_INVALID_VALIDATION_INVOCATION
- FST_ERR_SCH_MISSING_ID
- FST_ERR_SCH_ALREADY_PRESENT
- FST_ERR_SCH_CONTENT_MISSING_SCHEMA
- FST_ERR_SCH_DUPLICATE
- FST_ERR_SCH_VALIDATION_BUILD
- FST_ERR_SCH_SERIALIZATION_BUILD
- FST_ERR_SCH_RESPONSE_SCHEMA_NOT_NESTED_2XX
- FST_ERR_HTTP2_INVALID_VERSION
- FST_ERR_INIT_OPTS_INVALID
- FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE
- FST_ERR_DUPLICATED_ROUTE
- FST_ERR_BAD_URL
- FST_ERR_ASYNC_CONSTRAINT
- FST_ERR_INVALID_URL
- FST_ERR_ROUTE_OPTIONS_NOT_OBJ
- FST_ERR_ROUTE_DUPLICATED_HANDLER
- FST_ERR_ROUTE_HANDLER_NOT_FN
- FST_ERR_ROUTE_MISSING_HANDLER
- FST_ERR_ROUTE_METHOD_INVALID
- FST_ERR_ROUTE_METHOD_NOT_SUPPORTED
- FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED
- FST_ERR_ROUTE_BODY_LIMIT_OPTION_NOT_INT
- FST_ERR_ROUTE_REWRITE_NOT_STR
- FST_ERR_REOPENED_CLOSE_SERVER
- FST_ERR_REOPENED_SERVER
- FST_ERR_PLUGIN_VERSION_MISMATCH
- FST_ERR_PLUGIN_CALLBACK_NOT_FN
- FST_ERR_PLUGIN_NOT_VALID
- FST_ERR_ROOT_PLG_BOOTED
- FST_ERR_PARENT_PLUGIN_BOOTED
- FST_ERR_PLUGIN_TIMEOUT
- FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE
- FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER
- FST_ERR_VALIDATION
- FST_ERR_LISTEN_OPTIONS_INVALID
- FST_ERR_ERROR_HANDLER_NOT_FN
Node.js 中的错误处理
未捕获的错误
在 Node.js 中,未捕获的错误可能会导致内存泄漏、文件描述符泄漏以及其他主要的生产问题。域 是解决此问题的失败尝试。
鉴于无法明智地处理所有未捕获的错误,处理它们的最佳方法是崩溃。
捕获 Promise 中的错误
如果您使用的是 promise,则应同步附加 .catch()
处理程序。
Fastify 中的错误
Fastify 遵循全有或全无的方法,并力求尽可能精简和优化。开发人员负责确保正确处理错误。
输入数据中的错误
大多数错误都是由于意外的输入数据导致的,因此我们建议根据 JSON 模式验证您的输入数据。
在 Fastify 中捕获未捕获的错误
Fastify 尝试在不影响性能的情况下捕获尽可能多的未捕获错误。这包括
- 同步路由,例如
app.get('/', () => { throw new Error('kaboom') })
async
路由,例如app.get('/', async () => { throw new Error('kaboom') })
在这两种情况下,错误都将被安全地捕获并路由到 Fastify 的默认错误处理程序,以获取通用的 500 内部服务器错误
响应。
要自定义此行为,您应该使用setErrorHandler
。
Fastify 生命周期钩子中的错误和自定义错误处理程序
来自钩子文档
如果在执行钩子期间发生错误,只需将其传递给
done()
,Fastify 将自动关闭请求并将相应的错误代码发送给用户。
当通过setErrorHandler
定义了自定义错误处理程序时,自定义错误处理程序将接收传递给 done()
回调(或通过其他支持的自动错误处理机制)的错误。如果 setErrorHandler
已多次使用以定义多个处理程序,则错误将被路由到在错误封装上下文中定义的最优先的处理程序。错误处理程序是完全封装的,因此插件中的 setErrorHandler
调用将限制错误处理程序到该插件的上下文。
根错误处理程序是 Fastify 的通用错误处理程序。此错误处理程序将使用 Error
对象中的标头和状态代码(如果存在)。如果提供了自定义错误处理程序,则不会自动设置标头和状态代码。
在您的自定义错误处理程序中需要注意的一些事项
您可以
reply.send(data)
,其行为与常规路由处理程序中的行为相同- 对象被序列化,如果已定义,则触发
preSerialization
生命周期钩子 - 字符串、缓冲区和流被发送到客户端,并带有相应的标头(无序列化)
- 对象被序列化,如果已定义,则触发
您可以在自定义错误处理程序中抛出一个新的错误 - 错误(新错误或重新抛出的接收到的错误参数) - 将调用父
errorHandler
。onError
钩子将仅为第一个抛出的错误触发一次。- 生命周期钩子不会触发两次错误 - Fastify 在内部监视错误调用,以避免在生命周期的响应阶段(路由处理程序之后的阶段)中抛出错误时出现无限循环。
当通过setErrorHandler
使用 Fastify 的自定义错误处理时,您应该了解错误如何在自定义错误处理程序和默认错误处理程序之间传播。
如果插件的错误处理程序重新抛出一个错误,并且该错误不是 Error 的实例(如以下示例中的 /bad
路由中所示),它将不会传播到父上下文错误处理程序。相反,它将被默认错误处理程序捕获。
为了确保一致的错误处理,建议抛出 Error
的实例。例如,在以下示例中,将 /bad
路由中的 throw 'foo'
替换为 throw new Error('foo')
可确保错误按预期通过自定义错误处理链传播。此做法有助于避免在 Fastify 中使用自定义错误处理时出现潜在的陷阱。
例如
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 错误代码
您可以访问 errorCodes
进行映射
// ESM
import { errorCodes } from 'fastify'
// CommonJs
const errorCodes = require('fastify').errorCodes
例如
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 使用的所有错误代码。