Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
@dotcom-reliability-kit/errors
Advanced tools
A suite of error classes which help you throw the most appropriate error in any situation
A suite of error classes which help you throw the most appropriate error in any situation, and identify when errors are known vs unknown. This module is part of FT.com Reliability Kit.
Install @dotcom-reliability-kit/errors
as a dependency:
npm install --save @dotcom-reliability-kit/errors
Include in your code:
import {OperationalError} from '@dotcom-reliability-kit/errors';
// or
const {OperationalError} = require('@dotcom-reliability-kit/errors');
This module exports different Error classes which have different jobs. All can be imported in the same way as the example above.
OperationalError
The OperationalError
class is the base class for most other error types. "Operational" in this context means "we understand why this error has occurred", so by using this error type you're helping your team to understand when a thrown error is unexpected.
Joyent's Error Handling docs have a good explanation of Operational Errors.
It's always best to use a more specific error, e.g. UpstreamServiceError
, if one exists that suits your needs. So review the docs here to find the most suitable error.
OperationalError
can work in the same way as a normal error, expecting a message:
throw new OperationalError('example message');
You can alternatively construct an operational error with a data object. This accepts a code
property, which must be set to a unique identifier for the type of error which is occurring, and a message
property which contains a human-readable message:
throw new OperationalError({
message: 'example message',
code: 'EXAMPLE_CODE'
});
Error codes are normalized to be uppercase, alphanumeric, and underscore-delimited. Error properties can be accessed like any other property:
error.message // example message
error.code // EXAMPLE_CODE
You may also pass additional properties into an error object, these will be collected and stored on a data
property on the error:
const error = new OperationalError({
message: 'example message',
code: 'EXAMPLE_CODE',
article: 'd92acacb-ac53-4505-aa88-eae4b42de994'
});
error.data.article // d92acacb-ac53-4505-aa88-eae4b42de994
OperationalError.relatesToSystems
The relatesToSystems
property of an operational error stores a list of FT systems which are related to the error that you're throwing.
This array could include:
OperationalError.cause
The cause
property of an operational error stores the root cause error instance, e.g. an error that has been caught as part of a try
/catch
block. It allows the operational error to include the diagnostic information captured by the root cause error.
OperationalError.isErrorMarkedAsOperational()
You can test whether an error is operational (known about) either by using the isErrorMarkedAsOperational
method. It accepts an error object of any kind and will return true
if that error has a truthy isOperational
property and false
otherwise:
OperationalError.isErrorMarkedAsOperational(new OperationalError('example message')); // true
OperationalError.isErrorMarkedAsOperational(new Error('example message')); // false
HttpError
The HttpError
class extends OperationalError
and represents an HTTP error status. It can work in the same way as a normal error, expecting a message. In this case it will represent an HTTP 500
:
throw new HttpError('example message');
You can alternatively construct an HTTP error with a data object. This accepts a statusCode
property, which is a valid HTTP status code number, as well as all of the properties you can set in OperationalError
:
throw new HttpError({
message: 'your thing was not found',
statusCode: 404
});
It's also possible to create an HTTP error with a status code alone, which will default the message to the corresponding HTTP status message:
throw new HttpError(404);
Error properties can be accessed like any other property:
error.message // your thing was not found
error.statusCode // 404
error.status // 404
error.statusMessage // Not Found
error.code // HTTP_404
http-errors
?The benefit of using this error rather than the excellent http-errors library is that we extend OperationalError
by default. This means that all HTTP errors you throw are considered "known errors" by the rest of our tooling. We also set a code
property by default which results in less code in our monitoring dashboards – we don't need to check both code
and statusCode
properties to determine the type of error thrown.
DataStoreError
The DataStoreError
class extends OperationalError
and represents an error which occurred while accessing a data store, e.g. MongoDB, PostgreSQL, or Redis. It has all of the features of operational errors, you can construct with just a message:
throw new DataStoreError('Could not connect to Redis');
You can alternatively construct a data store error with a data object. You can use any of the properties defined in OperationalError
:
throw new DataStoreError({
code: 'REDIS_CONNECTION_FAILED',
message: 'Could not connect to Redis',
});
UpstreamServiceError
The UpstreamServiceError
class extends HttpError
and represents an error which occurred while connecting to an upstream service, e.g. an FT or third-party API. It has all of the features of operational and HTTP errors, you can construct with just a message:
throw new UpstreamServiceError('Content could not be fetched');
The HTTP status code defaults to a 502. This indicates that while connecting to an upstream service, your system has received a response that it cannot serve to an end user.
You can alternatively construct an upstream service error with a data object. You can use any of the properties defined in HttpError
and OperationalError
:
throw new UpstreamServiceError({
code: 'CONTENT_PIPELINE_FAILED',
message: 'Content could not be fetched, the content pipeline is responding with a 503 status',
statusCode: 503,
relatesToSystems: ['cp-content-pipeline-graphql']
});
UserInputError
The UserInputError
class extends HttpError
and represents an error which occurred based on invalid user input, e.g. they inputted a malformed email address into a form. It has all of the features of operational and HTTP errors but defaults to a 400
status code. You can construct with just a message:
throw new UserInputError('An invalid email address was input');
You can alternatively construct a user input error with a data object. You can use any of the properties defined in HttpError
and OperationalError
:
throw new UserInputError({
code: 'REGISTRATION_INFO_INVALID',
message: 'An invalid email address was input'
});
See the central contributing guide for Reliability Kit.
Licensed under the MIT license.
Copyright © 2022, The Financial Times Ltd.
FAQs
A suite of error classes which help you throw the most appropriate error in any situation
The npm package @dotcom-reliability-kit/errors receives a total of 1,818 weekly downloads. As such, @dotcom-reliability-kit/errors popularity was classified as popular.
We found that @dotcom-reliability-kit/errors demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.