Node.js Error Handling

The Node.js Error Class Hierarchy

The Node.js error class hierarchy consists of about half a dozen unique classes, most of which inherit from the baseline Error class. A Node.js application will typically experience errors that fall into one of four categories:

  • Standard JavaScript errors like RangeError, ReferenceError, and TypeError.
  • System-level errors from the underlying operating system. These might occur due to invalid IO calls or insufficient memory issues.
  • User errors generated by application code. These are the typical type of errors you’ll likely think of when evaluating errors in most programming languages.
  • Assertion Errors, which are a special error type triggered whenever Node.js detects a logic violation.

One important distinction between Node.js and standard JavaScript is that all exceptions thrown by Node.js are instances of the Error class. This allows Node.js to associate the stack trace and other valuable metadata with every error that occurs within a Node.js application.

Here is the full Node.js error class hierarchy:

  • Class: Error
    • Class: AssertionError
    • Class: RangeError
    • Class: ReferenceError
    • Class: SyntaxError
    • Class: TypeError
    • Class: System Error

Node.js Error Codes

Beyond the Error class and its children, starting with version 8+ Node.js now associates an error code property with each error that is thrown. These codes are simply string constants, but their existence allows code to check for a specific error type without having to worry about the messiness associated with checking the actual error message property string.

For example, in the past performing logic based on a specific caught error type involved something like this:

Comparing strings is a rather messy affair, particularly when internationalization gets involved with various locales. Thus, Node.js error codes were introduced and allow the error.code property to be checked against a standard string constant associated with the type of error you’re checking for. Thus, the code above using error codes looks something like this:

The full list of Node.js error codes can be found below:

  • Node.js Error Codes
    • ERR_ARG_NOT_ITERABLE
    • ERR_ASSERTION
    • ERR_ASYNC_CALLBACK
    • ERR_ASYNC_TYPE
    • ERR_BUFFER_OUT_OF_BOUNDS
    • ERR_BUFFER_TOO_LARGE
    • ERR_CHILD_CLOSED_BEFORE_REPLY
    • ERR_CONSOLE_WRITABLE_STREAM
    • ERR_CPU_USAGE
    • ERR_CRYPTO_ECDH_INVALID_FORMAT
    • ERR_CRYPTO_ENGINE_UNKNOWN
    • ERR_CRYPTO_FIPS_FORCED
    • ERR_CRYPTO_FIPS_UNAVAILABLE
    • ERR_CRYPTO_HASH_DIGEST_NO_UTF16
    • ERR_CRYPTO_HASH_FINALIZED
    • ERR_CRYPTO_HASH_UPDATE_FAILED
    • ERR_CRYPTO_INVALID_DIGEST
    • ERR_CRYPTO_SIGN_KEY_REQUIRED
    • ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH
    • ERR_DNS_SET_SERVERS_FAILED
    • ERR_ENCODING_INVALID_ENCODED_DATA
    • ERR_ENCODING_NOT_SUPPORTED
    • ERR_FALSY_VALUE_REJECTION
    • ERR_HTTP_HEADERS_SENT
    • ERR_HTTP_INVALID_CHAR
    • ERR_HTTP_INVALID_STATUS_CODE
    • ERR_HTTP_TRAILER_INVALID
    • ERR_HTTP2_CONNECT_AUTHORITY
    • ERR_HTTP2_CONNECT_PATH
    • ERR_HTTP2_CONNECT_SCHEME
    • ERR_HTTP2_FRAME_ERROR
    • ERR_HTTP2_HEADER_REQUIRED
    • ERR_HTTP2_HEADER_SINGLE_VALUE
    • ERR_HTTP2_HEADERS_AFTER_RESPOND
    • ERR_HTTP2_HEADERS_OBJECT
    • ERR_HTTP2_HEADERS_SENT
    • ERR_HTTP2_INFO_HEADERS_AFTER_RESPOND
    • ERR_HTTP2_INFO_STATUS_NOT_ALLOWED
    • ERR_HTTP2_INVALID_CONNECTION_HEADERS
    • ERR_HTTP2_INVALID_HEADER_VALUE
    • ERR_HTTP2_INVALID_INFO_STATUS
    • ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH
    • ERR_HTTP2_INVALID_PSEUDOHEADER
    • ERR_HTTP2_INVALID_SESSION
    • ERR_HTTP2_INVALID_SETTING_VALUE
    • ERR_HTTP2_INVALID_STREAM
    • ERR_HTTP2_MAX_PENDING_SETTINGS_ACK
    • ERR_HTTP2_NO_SOCKET_MANIPULATION
    • ERR_HTTP2_OUT_OF_STREAMS
    • ERR_HTTP2_PAYLOAD_FORBIDDEN
    • ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED
    • ERR_HTTP2_PUSH_DISABLED
    • ERR_HTTP2_SEND_FILE
    • ERR_HTTP2_SOCKET_BOUND
    • ERR_HTTP2_STATUS_101
    • ERR_HTTP2_STATUS_INVALID
    • ERR_HTTP2_STREAM_CLOSED
    • ERR_HTTP2_STREAM_ERROR
    • ERR_HTTP2_STREAM_SELF_DEPENDENCY
    • ERR_HTTP2_UNSUPPORTED_PROTOCOL
    • ERR_INDEX_OUT_OF_RANGE
    • ERR_INSPECTOR_ALREADY_CONNECTED
    • ERR_INSPECTOR_CLOSED
    • ERR_INSPECTOR_NOT_AVAILABLE
    • ERR_INSPECTOR_NOT_CONNECTED
    • ERR_INVALID_ARG_TYPE
    • ERR_INVALID_ARG_VALUE
    • ERR_INVALID_ARRAY_LENGTH
    • ERR_INVALID_ASYNC_ID
    • ERR_INVALID_BUFFER_SIZE
    • ERR_INVALID_CALLBACK
    • ERR_INVALID_CHAR
    • ERR_INVALID_CURSOR_POS
    • ERR_INVALID_DOMAIN_NAME
    • ERR_INVALID_FD
    • ERR_INVALID_FD_TYPE
    • ERR_INVALID_FILE_URL_HOST
    • ERR_INVALID_FILE_URL_PATH
    • ERR_INVALID_HANDLE_TYPE
    • ERR_INVALID_HTTP_TOKEN
    • ERR_INVALID_IP_ADDRESS
    • ERR_INVALID_OPT_VALUE
    • ERR_INVALID_OPT_VALUE_ENCODING
    • ERR_INVALID_PERFORMANCE_MARK
    • ERR_INVALID_PROTOCOL
    • ERR_INVALID_REPL_EVAL_CONFIG
    • ERR_INVALID_SYNC_FORK_INPUT
    • ERR_INVALID_THIS
    • ERR_INVALID_TUPLE
    • ERR_INVALID_URI
    • ERR_INVALID_URL
    • ERR_INVALID_URL_SCHEME
    • ERR_IPC_CHANNEL_CLOSED
    • ERR_IPC_DISCONNECTED
    • ERR_IPC_ONE_PIPE
    • ERR_IPC_SYNC_FORK
    • ERR_METHOD_NOT_IMPLEMENTED
    • ERR_MISSING_ARGS
    • ERR_MISSING_DYNAMIC_INSTANTIATE_HOOK
    • ERR_MISSING_MODULE
    • ERR_MODULE_RESOLUTION_LEGACY
    • ERR_MULTIPLE_CALLBACK
    • ERR_NAPI_CONS_FUNCTION
    • ERR_NAPI_CONS_PROTOTYPE_OBJECT
    • ERR_NO_CRYPTO
    • ERR_NO_ICU
    • ERR_NO_LONGER_SUPPORTED
    • ERR_OUTOFMEMORY
    • ERR_OUT_OF_RANGE
    • ERR_PARSE_HISTORY_DATA
    • ERR_REQUIRE_ESM
    • ERR_SERVER_ALREADY_LISTEN
    • ERR_SOCKET_ALREADY_BOUND
    • ERR_SOCKET_BAD_BUFFER_SIZE
    • ERR_SOCKET_BAD_PORT
    • ERR_SOCKET_BAD_TYPE
    • ERR_SOCKET_BUFFER_SIZE
    • ERR_SOCKET_CANNOT_SEND
    • ERR_SOCKET_CLOSED
    • ERR_SOCKET_DGRAM_NOT_RUNNING
    • ERR_STDERR_CLOSE
    • ERR_STDOUT_CLOSE
    • ERR_STREAM_CANNOT_PIPE
    • ERR_STREAM_NULL_VALUES
    • ERR_STREAM_PUSH_AFTER_EOF
    • ERR_STREAM_READ_NOT_IMPLEMENTED
    • ERR_STREAM_UNSHIFT_AFTER_END_EVENT
    • ERR_STREAM_WRAP
    • ERR_STREAM_WRITE_AFTER_END
    • ERR_TLS_CERT_ALTNAME_INVALID
    • ERR_TLS_DH_PARAM_SIZE
    • ERR_TLS_HANDSHAKE_TIMEOUT
    • ERR_TLS_RENEGOTIATION_FAILED
    • ERR_TLS_REQUIRED_SERVER_NAME
    • ERR_TLS_SESSION_ATTACK
    • ERR_TRANSFORM_ALREADY_TRANSFORMING
    • ERR_TRANSFORM_WITH_LENGTH_0
    • ERR_UNESCAPED_CHARACTERS
    • ERR_UNHANDLED_ERROR
    • ERR_UNKNOWN_ENCODING
    • ERR_UNKNOWN_FILE_EXTENSION
    • ERR_UNKNOWN_MODULE_FORMAT
    • ERR_UNKNOWN_SIGNAL
    • ERR_UNKNOWN_STDIN_TYPE
    • ERR_UNKNOWN_STREAM_TYPE
    • ERR_V8BREAKITERATOR
    • ERR_VALID_PERFORMANCE_ENTRY_TYPE
    • ERR_VALUE_OUT_OF_RANGE
    • ERR_ZLIB_BINDING_CLOSED
    • ERR_ZLIB_INITIALIZATION_FAILED

As we publish future error-specific articles in this series we’ll update the full list above with relevant tutorial and article links for each error class and error code, so this post can act as a go-to resource for Node.js error handling tips.

Major Error Classes Overview

Let’s briefly look at each top-level error class type found in Node.js. These top-level errors will server as a basis for exploring specific errors and error codes in future articles.

Error

The Error class is a generic JavaScript Error object that doesn’t include any information about why this error occurred. However, since these are Node.js-generated Errors, each Error instance includes a stack trace, error code (if applicable), and any other relevant metadata. This metadata is provided via a handful of core Error class properties:

  • error.code – A string constant indicating the specific error type.
  • error.message – A string that describes the error.
  • error.stack – A string that describes where in the code the Error occurred.

As we saw above, since all errors in Node.js inherit from the Error class, all errors will include these baseline properties.

AssertionError

Indicates an assertion failure using the assert module.

RangeError

Indicates that an argument was not within a valid set or range of values. Node.js generates and throws RangeErrors immediately when invalid arguments are detected.

ReferenceError

Indicates that an undefined variable was accessed.

SyntaxError

Indicates that a portion of the code is not valid JavaScript. Typically, SyntaxErrors will only occur as a result of code evaluation techniques, such as using the Function() or eval() functions.

TypeError

Indicates that an argument was passed to a function that expected an argument of a different type. Similar to the RangeError, Node.js will generate and throw TypeErrors immediately when an invalid argument type is detected.

System Error

As discussed in the introduction, one of the four common categories in which Node.js can experience errors is when something at the system level goes wrong. In such cases, a System Error is generated. These may occur due to improper IO operations, invalid permissions, and so forth.

In addition to the error.code property found in the inherited Error class, System Errors also include a few extra properties that are relevant to system level problems:

  • error.errno – A number or string value indicating the error number associated with the particular system-level error.code.
  • error.syscall – A string that describes the syscall that failed.
  • error.address – An optional string that describes the remote address for which the connection-related error occurred.
  • error.port – An optional number that describes the remote port for which the connection-related error occurred.

There are far too many possible System Error codes that can occur, but feel free to look at the man page documentation for more information.


That’s just a small taste of overall Node.js error class hierarchy. Stay tuned for more in-depth articles examining each of these error in greater detail, and be sure to check out Airbrake’s robust error monitoring software, which provides real-time error monitoring and automatic exception reporting for all your development projects. Airbrake’s state of the art web dashboard ensures you receive round-the-clock status updates on your application’s health and error rates. No matter what you’re working on, Airbrake easily integrates with all the most popular languages and frameworks. Plus, Airbrake makes it easy to customize exception parameters, while giving you complete control of the active error filter system, so you only gather the errors that matter most.

Check out Airbrake’s error monitoring software today and see for yourself why so many of the world’s best engineering teams use Airbrake to revolutionize their exception handling practices!