@xtreamsrl/nest-exception
v1.5.1
Published
A Nestjs global exception filter to handle exceptions and standardize error responses.
Downloads
803
Readme
@xtreamsrl/nest-exception
This package provides a NestJS global exception filter that uses a MessageSource
component to translate an exception into a
http error with a proper user-facing message.
The MessageSource
component is a generic interface that can be implemented to provide a way to translate an exception into
a user-facing message. The InMemoryMessageSource
is a simple implementation that uses a map to translate the exception code
into a message.
All exceptions will be logged and every error response will contain an incident id for troubleshooting purposes.
An incident id is a unique identifier that can be used to trace the error in the logs. The incident id is generated by the
IncidentIdSupplier
component. The OpenTelemetryIncidentIdSupplier
is an implementation that uses the OpenTelemetry trace id, if available.
You can also provide a custom ErrorContextSupplier
to add additional context to the logged error. For example, if the underlying
logger is the WinstonGCPLogger
, the context will be added to the log entry as metadata.
Installation
npm install @xtreamsrl/nest-exception
Usage
Define your custom exception that extends the BaseException
class and define your error messages map:
export class MyBaseException extends BaseException {
constructor(code: MyErrorCodes, message?: string, context?: ExceptionContext) {
super(code, message, context);
}
}
enum MyErrorCodes {
BAD_CONFIG = 'BAD_CONFIG'
}
// Error messages map
const errorMessages = {
ERR_GENERIC: 'Generic error',
BAD_CONFIG: 'bad configuration url',
} as const;
The enum is shared with the BaseException
, so that the code can be used as key to
return to the user an appropriate error message (which differ from the exception message).
At this point just create the exception filter and register it as the global one.
const app = moduleRef.createNestApplication();
const adapterHost = await app.get<HttpAdapterHost>(HttpAdapterHost);
const messageSource = new InMemoryMessageSource<MyErrorCodes>(errorMessages);
const logger = await app.resolve<LoggerServicePort>(LoggerServicePort);
const exceptionFilter = new RestExceptionFilter(adapterHost, new OpenTelemetryIncidentIdSupplier(), messageSource, logger);
app.useGlobalFilters(exceptionFilter);
Remember to use the error codes enum as generic param for the MessageSource
component, otherwise the string
type will be automatically inferred by Typescript.
Build
Run nx build nest-exception
to build the library.
Run unit tests
Run nx test nest-exception
to execute the unit tests via Jest.
Linting
Run nx lint nest-exception
to execute the lint via ESLint.
Versioning
Export the GH_TOKEN
environment variable with your GitHub token with at least the repo
scope:
export GH_TOKEN=<YOUR_PERSONAL_GH_TOKEN>
Then run the following command:
lerna version
The GH_TOKEN
is needed to push the version commit and tag to the remote repository and to create the release on GitHub.
For general information about the versioning process, please refer to the root Readme Versioning section.
Publishing
Update your local .npmrc
file to include the following lines:
@xtreamsrl:registry=https://registry.npmjs.org/
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
The ${NPM_TOKEN}
placeholder is a npm personal access token publish permissions on the @xtreamsrl
organization.
It can be treated as placeholder to replace with the actual token value, or you can set it as an environment variable:
export NPM_TOKEN=<YOUR_PERSONAL_NPM_TOKEN>
Then run the following command:
npm run lerna-publish