rembrembdocs

Version: latest (v5.8.x)

Errors

Table of contents

Error Handling In Node.js

Uncaught Errors

In Node.js, uncaught errors can cause memory leaks, file descriptor leaks, and other major production issues. Domains were a failed attempt to fix this.

Given that it is not possible to process all uncaught errors sensibly, the best way to deal with them is to crash.

Catching Errors In Promises

When using promises, attach a .catch() handler synchronously.

Errors In Fastify

Fastify follows an all-or-nothing approach and aims to be lean and optimal. The developer is responsible for ensuring errors are handled properly.

Errors In Input Data

Most errors result from unexpected input data, so it is recommended to validate input data against a JSON schema.

Catching Uncaught Errors In Fastify

Fastify tries to catch as many uncaught errors as possible without hindering performance. This includes:

  1. synchronous routes, e.g. app.get('/', () => { throw new Error('kaboom') })
  2. async routes, e.g. app.get('/', async () => { throw new Error('kaboom') })

In both cases, the error will be caught safely and routed to Fastify's default error handler, resulting in a generic 500 Internal Server Error response.

To customize this behavior, use setErrorHandler.

Errors In Fastify Lifecycle Hooks And A Custom Error Handler

From the Hooks documentation:

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.

When a custom error handler is defined through setErrorHandler, it will receive the error passed to the done() callback or through other supported automatic error handling mechanisms. If setErrorHandler is used multiple times, the error will be routed to the most precedent handler 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.

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.

The following should be considered when using a custom error handler:

When using Fastify's custom error handling through setErrorHandler, be aware of how errors are propagated between custom and default error handlers.

If a plugin's error handler re-throws an error that is not an instance of Error, it will not propagate to the parent context error handler. Instead, it will be caught by the default error handler. This can be seen in the /bad route of the example below.

To ensure consistent error handling, throw instances of Error. For example, replace throw 'foo' with throw new Error('foo') in the /bad route to ensure 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 frameworkconst fastify = Fastify({  logger: true})// Register parent error handlerfastify.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 serverfastify.listen({ port: 3000 }, function (err, address) {  if (err) {    fastify.log.error(err)    process.exit(1)  }  // Server is listening at ${address}})

Fastify Error Codes

You can access errorCodes for mapping:

// ESMimport { errorCodes } from 'fastify'// CommonJSconst errorCodes = require('fastify').errorCodes

For example:

const Fastify = require('fastify')// Instantiate the frameworkconst fastify = Fastify({  logger: true})// Declare a routefastify.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}})

Below is a table with all the error codes used by Fastify.

Code

Description

How to solve

Discussion

FST_ERR_NOT_FOUND

404 Not Found

-

#1168

FST_ERR_OPTIONS_NOT_OBJ

Fastify options wrongly specified.

Fastify options should be an object.

#4554

FST_ERR_QSP_NOT_FN

QueryStringParser wrongly specified.

QueryStringParser option should be a function.

#4554

FST_ERR_SCHEMA_CONTROLLER_BUCKET_OPT_NOT_FN

SchemaController.bucket wrongly specified.

SchemaController.bucket option should be a function.

#4554

FST_ERR_SCHEMA_ERROR_FORMATTER_NOT_FN

SchemaErrorFormatter option wrongly specified.

SchemaErrorFormatter option should be a non async function.

#4554

FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_OBJ

ajv.customOptions wrongly specified.

ajv.customOptions option should be an object.

#4554

FST_ERR_AJV_CUSTOM_OPTIONS_OPT_NOT_ARR

ajv.plugins option wrongly specified.

ajv.plugins option should be an array.

#4554

FST_ERR_CTP_ALREADY_PRESENT

The parser for this content type was already registered.

Use a different content type or delete the already registered parser.

#1168

FST_ERR_CTP_INVALID_TYPE

Content-Type wrongly specified

The Content-Type should be a string.

#1168

FST_ERR_CTP_EMPTY_TYPE

Content-Type is an empty string.

Content-Type cannot be an empty string.

#1168

FST_ERR_CTP_INVALID_HANDLER

Invalid handler for the content type.

Use a different handler.

#1168

FST_ERR_CTP_INVALID_PARSE_TYPE

The provided parse type is not supported.

Accepted values are string or buffer.

#1168

FST_ERR_CTP_BODY_TOO_LARGE

The request body is larger than the provided limit.

Increase the limit in the Fastify server instance setting: bodyLimit

#1168

FST_ERR_CTP_INVALID_MEDIA_TYPE

The received media type is not supported (i.e. there is no suitable Content-Type parser for it).

Use a different content type.

#1168

FST_ERR_CTP_INVALID_CONTENT_LENGTH

Request body size did not match Content-Length.

Check the request body size and the Content-Length header.

#1168

FST_ERR_CTP_EMPTY_JSON_BODY

Body is not valid JSON but content-type is set to application/json.

Check if the request body is valid JSON.

#5925

FST_ERR_CTP_INVALID_JSON_BODY

Body cannot be empty when content-type is set to application/json.

Check the request body.

#1253

FST_ERR_CTP_INSTANCE_ALREADY_STARTED

Fastify is already started.

-

#4554

FST_ERR_INSTANCE_ALREADY_LISTENING

Fastify instance is already listening.

-

#4554

FST_ERR_DEC_ALREADY_PRESENT

A decorator with the same name is already registered.

Use a different decorator name.

#1168

FST_ERR_DEC_DEPENDENCY_INVALID_TYPE

The dependencies of decorator must be of type Array.

Use an array for the dependencies.

#3090

FST_ERR_DEC_MISSING_DEPENDENCY

The decorator cannot be registered due to a missing dependency.

Register the missing dependency.

#1168

FST_ERR_DEC_AFTER_START

The decorator cannot be added after start.

Add the decorator before starting the server.

#2128

FST_ERR_DEC_REFERENCE_TYPE

The decorator cannot be a reference type.

Define the decorator with a getter/setter interface or an empty decorator with a hook.

#5462

FST_ERR_DEC_UNDECLARED

An attempt was made to access a decorator that has not been declared.

Declare the decorator before using it.

#5768

FST_ERR_HOOK_INVALID_TYPE

The hook name must be a string.

Use a string for the hook name.

#1168

FST_ERR_HOOK_INVALID_HANDLER

The hook callback must be a function.

Use a function for the hook callback.

#1168

FST_ERR_HOOK_INVALID_ASYNC_HANDLER

Async function has too many arguments. Async hooks should not use the done argument.

Remove the done argument from the async hook.

#4367

FST_ERR_HOOK_NOT_SUPPORTED

The hook is not supported.

Use a supported hook.

#4554

FST_ERR_MISSING_MIDDLEWARE

You must register a plugin for handling middlewares, visit Middleware for more info.

Register a plugin for handling middlewares.

#2014

FST_ERR_HOOK_TIMEOUT

A callback for a hook timed out.

Increase the timeout for the hook.

#3106

FST_ERR_LOG_INVALID_DESTINATION

The logger does not accept the specified destination.

Use a 'stream' or a 'file' as the destination.

#1168

FST_ERR_LOG_INVALID_LOGGER

The logger should have all these methods: 'info', 'error', 'debug', 'fatal', 'warn', 'trace', 'child'.

Use a logger with all the required methods.

#4520

FST_ERR_LOG_INVALID_LOGGER_INSTANCE

The loggerInstance only accepts a logger instance, not a configuration object.

To pass a configuration object, use 'logger' instead.

#5020

FST_ERR_LOG_INVALID_LOGGER_CONFIG

The logger option only accepts a configuration object, not a logger instance.

To pass an instance, use 'loggerInstance' instead.

#5020

FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED

You cannot provide both 'logger' and 'loggerInstance'.

Please provide only one option.

#5020

FST_ERR_REP_INVALID_PAYLOAD_TYPE

Reply payload can be either a string or a Buffer.

Use a string or a Buffer for the payload.

#1168

FST_ERR_REP_RESPONSE_BODY_CONSUMED

Using Response as reply payload, but the body is being consumed.

Make sure you don't consume the Response.body

#5286

FST_ERR_REP_READABLE_STREAM_LOCKED

Using ReadableStream as reply payload, but locked with another reader.

Make sure you don't call the Readable.getReader before sending or release lock with reader.releaseLock() before sending.

#5920

FST_ERR_REP_ALREADY_SENT

A response was already sent.

-

#1336

FST_ERR_REP_SENT_VALUE

The only possible value for reply.sent is true.

-

#1336

FST_ERR_SEND_INSIDE_ONERR

You cannot use send inside the onError hook.

-

#1348

FST_ERR_SEND_UNDEFINED_ERR

Undefined error has occurred.

-

#2074

FST_ERR_BAD_STATUS_CODE

The status code is not valid.

Use a valid status code.

#2082

FST_ERR_BAD_TRAILER_NAME

Called reply.trailer with an invalid header name.

Use a valid header name.

#3794

FST_ERR_BAD_TRAILER_VALUE

Called reply.trailer with an invalid type. Expected a function.

Use a function.

#3794

FST_ERR_FAILED_ERROR_SERIALIZATION

Failed to serialize an error.

-

#4601

FST_ERR_MISSING_SERIALIZATION_FN

Missing serialization function.

Add a serialization function.

#3970

FST_ERR_MISSING_CONTENTTYPE_SERIALIZATION_FN

Missing Content-Type serialization function.

Add a serialization function.

#4264

FST_ERR_REQ_INVALID_VALIDATION_INVOCATION

Invalid validation invocation. Missing validation function for HTTP part nor schema provided.

Add a validation function.

#3970

FST_ERR_SCH_MISSING_ID

The schema provided does not have $id property.

Add a $id property.

#1168

FST_ERR_SCH_ALREADY_PRESENT

A schema with the same $id already exists.

Use a different $id.

#1168

FST_ERR_SCH_CONTENT_MISSING_SCHEMA

A schema is missing for the corresponding content type.

Add a schema.

#4264

FST_ERR_SCH_DUPLICATE

Schema with the same attribute already present!

Use a different attribute.

#1954

FST_ERR_SCH_VALIDATION_BUILD

The JSON schema provided for validation to a route is not valid.

Fix the JSON schema.

#2023

FST_ERR_SCH_SERIALIZATION_BUILD

The JSON schema provided for serialization of a route response is not valid.

Fix the JSON schema.

#2023

FST_ERR_SCH_RESPONSE_SCHEMA_NOT_NESTED_2XX

Response schemas should be nested under a valid status code (2XX).

Use a valid status code.

#4554

FST_ERR_INIT_OPTS_INVALID

Invalid initialization options.

Use valid initialization options.

#1471

FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE

Cannot set forceCloseConnections to idle as your HTTP server does not support closeIdleConnections method.

Use a different value for forceCloseConnections.

#3925

FST_ERR_DUPLICATED_ROUTE

The HTTP method already has a registered controller for that URL.

Use a different URL or register the controller for another HTTP method.

#2954

FST_ERR_BAD_URL

The router received an invalid URL.

Use a valid URL.

#2106

FST_ERR_ASYNC_CONSTRAINT

The router received an error when using asynchronous constraints.

-

#4323

FST_ERR_INVALID_URL

URL must be a string.

Use a string for the URL.

#3653

FST_ERR_ROUTE_OPTIONS_NOT_OBJ

Options for the route must be an object.

Use an object for the route options.

#4554

FST_ERR_ROUTE_DUPLICATED_HANDLER

Duplicate handler for the route is not allowed.

Use a different handler.

#4554

FST_ERR_ROUTE_HANDLER_NOT_FN

Handler for the route must be a function.

Use a function for the handler.

#4554

FST_ERR_ROUTE_MISSING_HANDLER

Missing handler function for the route.

Add a handler function.

#4554

FST_ERR_ROUTE_METHOD_INVALID

Method is not a valid value.

Use a valid value for the method.

#4750

FST_ERR_ROUTE_METHOD_NOT_SUPPORTED

Method is not supported for the route.

Use a supported method.

#4554

FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED

Body validation schema route is not supported.

Use a different different method for the route.

#4554

FST_ERR_ROUTE_BODY_LIMIT_OPTION_NOT_INT

bodyLimit option must be an integer.

Use an integer for the bodyLimit option.

#4554

FST_ERR_HANDLER_TIMEOUT

Request timed out.

Increase the handlerTimeout option or optimize the handler.

-

FST_ERR_ROUTE_HANDLER_TIMEOUT_OPTION_NOT_INT

handlerTimeout option must be a positive integer.

Use a positive integer for the handlerTimeout option.

-

FST_ERR_ROUTE_REWRITE_NOT_STR

rewriteUrl needs to be of type string.

Use a string for the rewriteUrl.

#4554

FST_ERR_REOPENED_CLOSE_SERVER

Fastify has already been closed and cannot be reopened.

-

#2415

FST_ERR_REOPENED_SERVER

Fastify is already listening.

-

#2415

FST_ERR_PLUGIN_VERSION_MISMATCH

Installed Fastify plugin mismatched expected version.

Use a compatible version of the plugin.

#2549

FST_ERR_PLUGIN_CALLBACK_NOT_FN

Callback for a hook is not a function.

Use a function for the callback.

#3106

FST_ERR_PLUGIN_NOT_VALID

Plugin must be a function or a promise.

Use a function or a promise for the plugin.

#3106

FST_ERR_ROOT_PLG_BOOTED

Root plugin has already booted.

-

#3106

FST_ERR_PARENT_PLUGIN_BOOTED

Impossible to load plugin because the parent (mapped directly from avvio)

-

#3106

FST_ERR_PLUGIN_TIMEOUT

Plugin did not start in time.

Increase the timeout for the plugin.

#3106

FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE

The decorator is not present in the instance.

-

#4554

FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER

The plugin being registered mixes async and callback styles.

-

#5141

FST_ERR_VALIDATION

The Request failed the payload validation.

Check the request payload.

#4824

FST_ERR_LISTEN_OPTIONS_INVALID

Invalid listen options.

Check the listen options.

#4886

FST_ERR_ERROR_HANDLER_NOT_FN

Error Handler must be a function

Provide a function to setErrorHandler.

#5317