VelaVela
Techniques

Exception Filters

Exception filters handle errors thrown during request processing.

Exception filters catch errors thrown during request processing and control the error response sent to the client.

Default Behavior

When an HttpException is thrown, Vela returns a JSON response with the status code and message:

{
  "statusCode": 404,
  "message": "Cat not found"
}

Unhandled exceptions that are not an HttpException result in a 500 Internal Server Error.

HttpException Hierarchy

Vela provides built-in exception classes:

ExceptionStatus Code
BadRequestException400
UnauthorizedException401
ForbiddenException403
NotFoundException404
ConflictException409
UnprocessableEntityException422
TooManyRequestsException429
InternalServerErrorException500
import { NotFoundException } from '@velajs/vela';

@Get(':id')
findOne(@Param('id') id: string) {
  const spirit = this.spiritsService.findById(id);
  if (!spirit) {
    throw new NotFoundException('Spirit not found');
  }
  return spirit;
}

ExceptionFilter Interface

Create custom filters by implementing ExceptionFilter and decorating with @Catch():

import {
  Catch, ExceptionFilter, HttpException, ExecutionContext,
} from '@velajs/vela';

@Catch(HttpException)
class HttpExceptionFilter implements ExceptionFilter<HttpException> {
  catch(exception: HttpException, context: ExecutionContext) {
    return {
      error: exception.message,
      status: exception.getStatus(),
      path: context.getRequest().url,
    };
  }
}

The @Catch() decorator accepts one or more exception types. Omitting arguments catches all exceptions.

Binding Filters

Apply filters at the method or controller level with @UseFilters():

import { Controller, Get, UseFilters } from '@velajs/vela';

@Controller('spirits')
@UseFilters(HttpExceptionFilter)
class SpiritsController {
  @Get(':id')
  findOne(@Param('id') id: string) {
    throw new NotFoundException('Cat not found');
  }
}

Global Filters

Register filters globally to handle exceptions across the entire application:

const app = await VelaFactory.create(AppModule);
app.useGlobalFilters(new HttpExceptionFilter());

Or use the APP_FILTER injection token:

import { APP_FILTER } from '@velajs/vela';

@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
  ],
})
class AppModule {}

Resolution Order

Filters are resolved from the most specific to the most general: handler → controller → global. The first matching filter handles the exception.

Catch-All Filter

A filter without arguments in @Catch() handles any unhandled exception:

@Catch()
class AllExceptionsFilter implements ExceptionFilter {
  catch(exception: unknown, context: ExecutionContext) {
    const status = exception instanceof HttpException
      ? exception.getStatus()
      : 500;

    const message = exception instanceof Error
      ? exception.message
      : 'Internal server error';

    return { statusCode: status, message };
  }
}
Edit on GitHub

Last updated on

On this page