Error handling

Global ErrorsFilter for Zod, TypeORM, and internal errors.

ErrorsFilter is registered globally in main.ts and standardizes error responses for Zod validation, TypeORM errors, and internal failures.

typescript
const { httpAdapter } = app.get(HttpAdapterHost);
const loggingService = app.get(ILoggingService);

app.useGlobalFilters(new ErrorsFilter(httpAdapter, loggingService));
typescript
@Catch()
export class ErrorsFilter extends BaseExceptionFilter {
  constructor(
    httpAdapter: AbstractHttpAdapter | undefined,
    private readonly loggingService: ILoggingService,
  ) {
    super(httpAdapter);
  }

  async catch(exception: unknown, host: ArgumentsHost) {
    if (exception instanceof ZodError) {
      return this.sendErrorResponse(host, this.handleZodError(exception));
    }

    if (exception instanceof Error && isTypeOrmError(exception)) {
      return this.sendErrorResponse(host, this.handleTypeOrmError(exception));
    }

    if (exception instanceof HttpException) {
      return super.catch(exception, host);
    }

    const error =
      exception instanceof Error ? exception : new Error(String(exception));

    await this.reportError(error, host);

    return this.sendErrorResponse(host, {
      statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
      message: 'Erro interno do servidor.',
    });
  }
}

When a validator throws ZodError, the response is HTTP 400 with per-field details:

typescript
private handleZodError(exception: ZodError): ErrorResponse {
  const formatted = formatZodError(exception);

  return {
    statusCode: HttpStatus.BAD_REQUEST,
    message: formatted.message,
    errors: formatted.errors,
  };
}

Example response (missing name field on create):

json
{
  "statusCode": 400,
  "message": "O campo name é obrigatório.",
  "errors": [
    { "field": "name", "message": "O campo name é obrigatório." }
  ]
}

Constraint violations (unique, foreign key, etc.) are formatted with status and a friendly message via formatTypeOrmError().

NotFoundException, BadRequestException, and other HttpException types follow NestJS default behavior:

typescript
if (!person) {
  throw new NotFoundException('Pessoa não encontrada');
}

Any unknown error returns HTTP 500 with a generic message. The error is reported via ILoggingService.report() (request user + package name). If reporting fails, the filter falls back to Logger — without exposing details to the client.

typescript
interface ErrorResponse {
  statusCode: HttpStatus;
  message: string;
  errors?: ZodFieldError[];
}

Koala Nest

A facilitator for building NestJS APIs with DDD architecture. Code copied into your repository — readable, adaptable, and under your control.

Creator

igordrangel.com.br

Design, back-end, and product strategy.

Quick Commands

Global CLI and scripts in the generated project

  • bun install -g @koalarx/nest
  • kl-nest new
  • kl-nest add cache
  • bun run migration:run # CRUD template
  • kl-nest --help
© 2026 Koala NestBuilt for NestJS developers and AI-assisted workflows.