Skip to main content

HttpErrorHandler

Any errors that occur while processing an HTTP request that you have not caught in controllers, interceptors, or services go to DefaultHttpErrorHandler. This handler is passed to the DI registry at the route level.

You can create your own error handler by creating a class that implements the HttpErrorHandler interface:

import { Logger, Status, HttpErrorHandler, injectable, Req, RequestContext } from '@ditsmod/core';
import { randomUUID } from 'node:crypto';

@injectable()
export class MyHttpErrorHandler implements HttpErrorHandler {
constructor(protected logger: Logger) {}

handleError(err: Error, ctx: RequestContext) {
const message = err.message;
this.logger.log('error', { err, note: 'This is my implementation of HttpErrorHandler' });
if (!ctx.nodeRes.headersSent) {
const error = { error: { message } };
const headers = { 'x-requestId': randomUUID() };
ctx.sendJson(error, Status.INTERNAL_SERVER_ERROR, headers);
}
}
}

To add your new error handler centrally, you can do it directly in the root module:

import { rootModule, HttpErrorHandler } from '@ditsmod/core';
import { MyHttpErrorHandler } from './my-http-error-handler.js';

@rootModule({
// ...
providersPerRou: [{ token: HttpErrorHandler, useClass: MyHttpErrorHandler }],
exports: [HttpErrorHandler],
})
export class AppModule {}

Of course, if there are error handling specifics for a separate module or controller, you can just as easily add your new handler to its metadata without affecting other components of your application.

If you add such a handler to the metadata of a non-root module, you probably don't need to export it. On the other hand, if you want to write a custom error handling module and still want to export HttpErrorHandler from it, be aware that importing it into any module will require provider collisions to be resolved. This occurs because a default error handler has already been added to each module in your application, and when you import the module with its new error handler, the two error handlers collide. This can be easily resolved:

import { featureModule, HttpErrorHandler } from '@ditsmod/core';
import { ErrorHandlerModule } from './error-handler.module.js';

@featureModule({
// ...
import: [ErrorHandlerModule]
resolvedCollisionsPerRou: [
[HttpErrorHandler, ErrorHandlerModule],
],
})
export class SomeModule {}

As you can see, the collision is resolved in the resolvedCollisionsPerRou array because it occurs at the route level. You pass there an array of two elements, where the first element is the token with which a collision occurred, and the second element is the module from which you want to export this provider.

We remind you that provider collisions can only occur when importing modules. That is, if you create your own error handler locally within a particular module, there will be no collisions.