メインコンテンツにスキップ
バージョン: latest (v5.0.x)

エラー

エラー

目次

Node.js におけるエラー処理

捕捉されないエラー

Node.js では、捕捉されないエラーは、メモリリーク、ファイル記述子のリーク、その他の重大な本番環境の問題を引き起こす可能性があります。ドメインは、これを修正するための失敗した試みでした。

すべての捕捉されないエラーを適切に処理することは不可能であるため、それらに対処する最善の方法は、クラッシュすることです。

Promise でのエラー捕捉

Promise を使用している場合は、.catch() ハンドラーを同期的にアタッチする必要があります。

Fastify におけるエラー

Fastify はオールオアナッシングのアプローチに従い、可能な限り無駄がなく最適な状態を目指しています。開発者は、エラーが適切に処理されるようにする責任があります。

入力データにおけるエラー

ほとんどのエラーは予期しない入力データの結果であるため、JSON スキーマに対して入力データを検証することをお勧めします。

Fastify における捕捉されないエラーの捕捉

Fastify は、パフォーマンスを損なうことなく、できる限り多くの捕捉されないエラーを捕捉しようとします。これには、次のようなものが含まれます。

  1. 同期ルート (例: app.get('/', () => { throw new Error('kaboom') }))
  2. async ルート (例: app.get('/', async () => { throw new Error('kaboom') }))

どちらの場合も、エラーは安全に捕捉され、汎用的な 500 Internal Server Error レスポンスのために Fastify のデフォルトエラーハンドラーにルーティングされます。

この動作をカスタマイズするには、setErrorHandlerを使用する必要があります。

Fastify ライフサイクルフックおよびカスタムエラーハンドラーにおけるエラー

フックのドキュメントから

フックの実行中にエラーが発生した場合は、それを done() に渡すだけで、Fastify は自動的にリクエストを閉じ、適切なエラーコードをユーザーに送信します。

setErrorHandler を使用してカスタムエラーハンドラーが定義されている場合、カスタムエラーハンドラーは done() コールバックに渡されたエラー (またはその他のサポートされている自動エラー処理メカニズム) を受け取ります。setErrorHandler が複数回使用されて複数のハンドラーが定義されている場合、エラーは、エラー カプセル化コンテキスト内で定義された最も優先度の高いハンドラーにルーティングされます。エラーハンドラーは完全にカプセル化されているため、プラグイン内の setErrorHandler 呼び出しは、エラーハンドラーをそのプラグインのコンテキストに制限します。

ルートエラーハンドラーは、Fastify の汎用エラーハンドラーです。このエラーハンドラーは、Error オブジェクトにヘッダーとステータスコードが存在する場合、それらを使用します。カスタムエラーハンドラーが提供されている場合、ヘッダーとステータスコードは自動的に設定されません。

カスタムエラーハンドラーで考慮すべき点

  • 通常のルートハンドラーと同様に動作する reply.send(data) を使用できます。

    • オブジェクトはシリアライズされ、定義されている場合は preSerialization ライフサイクルフックがトリガーされます
    • 文字列、バッファー、ストリームは、適切なヘッダー付きでクライアントに送信されます (シリアライズなし)
  • カスタムエラーハンドラーで新しいエラーをスローできます - エラー (新しいエラーまたは再スローされた受信エラーパラメーター) - は親の errorHandler を呼び出します。

    • onError フックは、最初にスローされたエラーに対して 1 回のみトリガーされます。
    • エラーはライフサイクルフックから 2 回トリガーされることはありません - Fastify は内部的にエラーの呼び出しを監視して、ライフサイクルの reply フェーズ (ルートハンドラーの後) でスローされたエラーの無限ループを回避します。

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 が使用するすべてのエラーコードの表です。

コード説明解決方法議論
FST_ERR_NOT_FOUND404 Not Found-#1168
FST_ERR_OPTIONS_NOT_OBJFastify のオプションが誤って指定されています。Fastify のオプションはオブジェクトである必要があります。#4554
FST_ERR_QSP_NOT_FNQueryStringParser が誤って指定されています。QueryStringParser オプションは関数である必要があります。#4554
FST_ERR_SCHEMA_CONTROLLER_BUCKET_OPT_NOT_FNSchemaController.bucket が誤って指定されています。SchemaController.bucket オプションは関数である必要があります。#4554
FST_ERR_SCHEMA_ERROR_FORMATTER_NOT_FNSchemaErrorFormatter オプションが誤って指定されています。SchemaErrorFormatter オプションは非同期関数であってはいけません。#4554
FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_OBJajv.customOptions の指定が誤っています。ajv.customOptions オプションはオブジェクトである必要があります。#4554
FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_ARRajv.plugins オプションの指定が誤っています。ajv.plugins オプションは配列である必要があります。#4554
FST_ERR_CTP_ALREADY_PRESENTこのコンテンツタイプのパーサーはすでに登録されています。別のコンテンツタイプを使用するか、すでに登録されているパーサーを削除してください。#1168
FST_ERR_CTP_INVALID_TYPEContent-Type の指定が誤っています。Content-Type は文字列である必要があります。#1168
FST_ERR_CTP_EMPTY_TYPEContent-Type が空の文字列です。Content-Type は空の文字列にできません。#1168
FST_ERR_CTP_INVALID_HANDLERコンテンツタイプのハンドラーが無効です。別のハンドラーを使用してください。#1168
FST_ERR_CTP_INVALID_PARSE_TYPE指定されたパースタイプはサポートされていません。許可される値は string または buffer です。#1168
FST_ERR_CTP_BODY_TOO_LARGEリクエストボディが指定された制限を超えています。Fastifyサーバーインスタンスの設定で制限を増やしてください: bodyLimit#1168
FST_ERR_CTP_INVALID_MEDIA_TYPE受信したメディアタイプはサポートされていません (つまり、適切な Content-Type パーサーがありません)。別のコンテンツタイプを使用してください。#1168
FST_ERR_CTP_INVALID_CONTENT_LENGTHリクエストボディのサイズが Content-Length と一致しません。リクエストボディのサイズと Content-Length ヘッダーを確認してください。#1168
FST_ERR_CTP_EMPTY_JSON_BODYcontent-type が application/json に設定されている場合、ボディは空にできません。リクエストボディを確認してください。#1253
FST_ERR_CTP_INSTANCE_ALREADY_STARTEDFastify はすでに起動しています。-#4554
FST_ERR_INSTANCE_ALREADY_LISTENINGFastify インスタンスはすでにリッスンしています。-#4554
FST_ERR_DEC_ALREADY_PRESENT同じ名前のデコレーターがすでに登録されています。別のデコレーター名を使用してください。#1168
FST_ERR_DEC_DEPENDENCY_INVALID_TYPEデコレーターの依存関係は Array 型である必要があります。依存関係には配列を使用してください。#3090
FST_ERR_DEC_MISSING_DEPENDENCY依存関係が不足しているため、デコレーターを登録できません。不足している依存関係を登録してください。#1168
FST_ERR_DEC_AFTER_STARTデコレーターは起動後に追加できません。サーバーを起動する前にデコレーターを追加してください。#2128
FST_ERR_DEC_REFERENCE_TYPEデコレーターは参照型であってはいけません。getter/setter インターフェースを持つデコレーターまたはフックを持つ空のデコレーターで定義してください。#5462
FST_ERR_HOOK_INVALID_TYPEフック名は文字列である必要があります。フック名には文字列を使用してください。#1168
FST_ERR_HOOK_INVALID_HANDLERフックのコールバックは関数である必要があります。フックのコールバックには関数を使用してください。#1168
FST_ERR_HOOK_INVALID_ASYNC_HANDLER非同期関数は引数が多すぎます。非同期フックは done 引数を使用すべきではありません。非同期フックから done 引数を削除してください。#4367
FST_ERR_HOOK_NOT_SUPPORTEDこのフックはサポートされていません。サポートされているフックを使用してください。#4554
FST_ERR_MISSING_MIDDLEWAREミドルウェアを処理するためのプラグインを登録する必要があります。詳細についてはMiddlewareを参照してください。ミドルウェアを処理するためのプラグインを登録してください。#2014
FST_ERR_HOOK_TIMEOUTフックのコールバックがタイムアウトしました。フックのタイムアウトを増やしてください。#3106
FST_ERR_LOG_INVALID_DESTINATIONロガーは指定された宛先を受け入れません。宛先として 'stream' または 'file' を使用してください。#1168
FST_ERR_LOG_INVALID_LOGGERロガーには、'info''error''debug''fatal''warn''trace''child' のすべてのメソッドが必要です。必要なすべてのメソッドを持つロガーを使用してください。#4520
FST_ERR_LOG_INVALID_LOGGER_INSTANCEloggerInstance は、ロガーインスタンスのみを受け入れ、構成オブジェクトは受け入れません。構成オブジェクトを渡すには、代わりに 'logger' を使用してください。#5020
FST_ERR_LOG_INVALID_LOGGER_CONFIGlogger オプションは構成オブジェクトのみを受け入れ、ロガーインスタンスは受け入れません。インスタンスを渡すには、代わりに 'loggerInstance' を使用してください。#5020
FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED'logger''loggerInstance' の両方を指定することはできません。どちらか一方のオプションのみを指定してください。#5020
FST_ERR_REP_INVALID_PAYLOAD_TYPEReply ペイロードは string または Buffer のいずれかになります。ペイロードには string または Buffer を使用してください。#1168
FST_ERR_REP_RESPONSE_BODY_CONSUMEDResponse を reply ペイロードとして使用していますが、ボディが消費されています。Response.body を消費していないことを確認してください。#5286
FST_ERR_REP_ALREADY_SENTレスポンスはすでに送信されました。-#1336
FST_ERR_REP_SENT_VALUEreply.sent の可能な値は true のみです。-#1336
FST_ERR_SEND_INSIDE_ONERRonError フック内で send を使用することはできません。-#1348
FST_ERR_SEND_UNDEFINED_ERR未定義のエラーが発生しました。-#2074
FST_ERR_BAD_STATUS_CODEステータスコードが無効です。有効なステータスコードを使用してください。#2082
FST_ERR_BAD_TRAILER_NAME無効なヘッダー名で reply.trailer が呼び出されました。有効なヘッダー名を使用してください。#3794
FST_ERR_BAD_TRAILER_VALUE無効な型で reply.trailer が呼び出されました。関数が期待されます。関数を使用してください。#3794
FST_ERR_FAILED_ERROR_SERIALIZATIONエラーのシリアル化に失敗しました。-#4601
FST_ERR_MISSING_SERIALIZATION_FNシリアル化関数が見つかりません。シリアル化関数を追加してください。#3970
FST_ERR_MISSING_CONTENTTYPE_SERIALIZATION_FNContent-Type のシリアル化関数が見つかりません。シリアル化関数を追加してください。#4264
FST_ERR_REQ_INVALID_VALIDATION_INVOCATION無効なバリデーション呼び出しです。HTTP パートのバリデーション関数もスキーマも提供されていません。バリデーション関数を追加してください。#3970
FST_ERR_SCH_MISSING_ID提供されたスキーマに $id プロパティがありません。$id プロパティを追加してください。#1168
FST_ERR_SCH_ALREADY_PRESENT同じ $id のスキーマがすでに存在します。別の $id を使用してください。#1168
FST_ERR_SCH_CONTENT_MISSING_SCHEMA対応するコンテンツタイプのスキーマが見つかりません。スキーマを追加してください。#4264
FST_ERR_SCH_DUPLICATE同じ属性を持つスキーマがすでに存在します。別の属性を使用してください。#1954
FST_ERR_SCH_VALIDATION_BUILDルートのバリデーションに提供された JSON スキーマが無効です。JSON スキーマを修正してください。#2023
FST_ERR_SCH_SERIALIZATION_BUILDルートレスポンスのシリアル化に提供された JSON スキーマが無効です。JSON スキーマを修正してください。#2023
FST_ERR_SCH_RESPONSE_SCHEMA_NOT_NESTED_2XXレスポンススキーマは有効なステータスコード (2XX) の下にネストする必要があります。有効なステータスコードを使用してください。#4554
FST_ERR_HTTP2_INVALID_VERSIONHTTP2 は node >= 8.8.1 からのみ利用可能です。より高いバージョンの node を使用してください。#1346
FST_ERR_INIT_OPTS_INVALID無効な初期化オプションです。有効な初期化オプションを使用してください。#1471
FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLEHTTPサーバーが closeIdleConnections メソッドをサポートしていないため、forceCloseConnections を idle に設定できません。forceCloseConnections に別の値を使用してください。#3925
FST_ERR_DUPLICATED_ROUTEHTTP メソッドには、その URL 用の登録済みコントローラーがすでにあります。別の URL を使用するか、別の HTTP メソッドのコントローラーを登録してください。#2954
FST_ERR_BAD_URLルーターが無効な URL を受信しました。有効な URL を使用してください。#2106
FST_ERR_ASYNC_CONSTRAINT非同期制約の使用中にルーターがエラーを受信しました。-#4323
FST_ERR_INVALID_URLURL は文字列である必要があります。URL には文字列を使用してください。#3653
FST_ERR_ROUTE_OPTIONS_NOT_OBJルートのオプションはオブジェクトである必要があります。ルートオプションにはオブジェクトを使用してください。#4554
FST_ERR_ROUTE_DUPLICATED_HANDLERルートの重複したハンドラーは許可されていません。別のハンドラーを使用してください。#4554
FST_ERR_ROUTE_HANDLER_NOT_FNルートのハンドラーは関数である必要があります。ハンドラーには関数を使用してください。#4554
FST_ERR_ROUTE_MISSING_HANDLERルートのハンドラー関数が見つかりません。ハンドラー関数を追加してください。#4554
FST_ERR_ROUTE_METHOD_INVALIDメソッドは無効な値です。メソッドには有効な値を使用してください。#4750
FST_ERR_ROUTE_METHOD_NOT_SUPPORTEDルートでメソッドがサポートされていません。サポートされているメソッドを使用してください。#4554
FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTEDボディバリデーションスキーマルートはサポートされていません。ルートには別のメソッドを使用してください。#4554
FST_ERR_ROUTE_BODY_LIMIT_OPTION_NOT_INTbodyLimit オプションは整数である必要があります。bodyLimit オプションには整数を使用してください。#4554
FST_ERR_ROUTE_REWRITE_NOT_STRrewriteUrlstring 型である必要があります。rewriteUrl には文字列を使用してください。#4554
FST_ERR_REOPENED_CLOSE_SERVERFastify はすでに閉じられており、再度開くことはできません。-#2415
FST_ERR_REOPENED_SERVERFastify はすでにリッスンしています。-#2415
FST_ERR_PLUGIN_VERSION_MISMATCHインストールされた Fastify プラグインが、期待されるバージョンと一致しません。互換性のあるバージョンのプラグインを使用してください。#2549
FST_ERR_PLUGIN_CALLBACK_NOT_FNフックのコールバックが関数ではありません。コールバックには関数を使用してください。#3106
FST_ERR_PLUGIN_NOT_VALIDプラグインは関数または Promise である必要があります。プラグインには関数または Promise を使用してください。#3106
FST_ERR_ROOT_PLG_BOOTEDルートプラグインはすでに起動しています。-#3106
FST_ERR_PARENT_PLUGIN_BOOTED親 (avvio から直接マッピングされた) のため、プラグインをロードできません。-#3106
FST_ERR_PLUGIN_TIMEOUTプラグインが時間内に開始されませんでした。プラグインのタイムアウトを増やしてください。#3106
FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCEデコレーターがインスタンスに存在しません。-#4554
FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER登録されているプラグインは、非同期スタイルとコールバックスタイルを混在させています。-#5141
FST_ERR_VALIDATIONリクエストがペイロードバリデーションに失敗しました。リクエストペイロードを確認してください。#4824
FST_ERR_LISTEN_OPTIONS_INVALID無効な listen オプションです。listen オプションを確認してください。#4886
FST_ERR_ERROR_HANDLER_NOT_FNエラーハンドラーは関数である必要があります。setErrorHandler に関数を提供してください。#5317