錯誤
錯誤
目錄
- 錯誤
- 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 中,未捕獲的錯誤很可能會導致記憶體洩漏、檔案描述符洩漏和其他重大的生產問題。域 (Domains) 是修正這個問題的失敗嘗試。
鑑於無法合理地處理所有未捕獲的錯誤,處理它們的最佳方法是崩潰。
在 Promise 中捕獲錯誤
如果您正在使用 promise,您應該同步附加一個 .catch()
處理器。
Fastify 中的錯誤
Fastify 遵循全有或全無的方法,並盡可能地保持精簡和最佳化。開發人員有責任確保正確處理錯誤。
輸入資料中的錯誤
大多數錯誤都是由於意外的輸入資料造成的,因此我們建議根據 JSON schema 驗證您的輸入資料。
在 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 使用的所有錯誤代碼的表格。