JSPM

@xavierdev25/rfc7807-errors

0.1.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 19
  • Score
    100M100P100Q81607F
  • License MIT

NestJS global exception filter implementing RFC 7807 Problem Details for HTTP APIs

Package Exports

  • @xavierdev25/rfc7807-errors
  • @xavierdev25/rfc7807-errors/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@xavierdev25/rfc7807-errors) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

@xavierdev25/rfc7807-errors

Global NestJS exception filter implementing RFC 7807 Problem Details (application/problem+json) for HTTP APIs.

Turns every error your API throws — your own domain errors, NestJS HttpExceptions, and unexpected crashes — into a single, standard, machine-readable error shape:

{
  "type": "https://api.example.com/errors/not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "Transaction with ID '…' was not found.",
  "instance": "/transactions/123",
  "transactionId": "123"
}

Built with SOLID in mind: an abstract ProblemDetailException, eight concrete LSP-correct subclasses, a framework-agnostic filter (Express/Fastify via HttpAdapterHost), and a pluggable serializer (DIP).

Install

pnpm add @xavierdev25/rfc7807-errors
# peer deps: @nestjs/common, @nestjs/core, rxjs

Quick start

import { Module } from '@nestjs/common';
import { Rfc7807Module } from '@xavierdev25/rfc7807-errors';

@Module({
  imports: [
    Rfc7807Module.forRoot({
      // Type URIs become `${typeBaseUri}/${error-slug}` (default: 'about:blank')
      typeBaseUri: 'https://api.example.com/errors',
      // Stack traces are added only when NODE_ENV !== 'production'
      includeStackTrace: process.env.NODE_ENV !== 'production',
      // Hook for logging / metrics / error tracking
      onProblem: (problem, exception) => logger.error(problem.title, exception),
    }),
  ],
})
export class AppModule {}

forRoot registers the Rfc7807ExceptionFilter globally (APP_FILTER). No manual useGlobalFilters needed.

Throwing problems

Eight ready-made exceptions, one per common HTTP status:

Class Status
BadRequestProblem 400
UnauthorizedProblem 401
ForbiddenProblem 403
NotFoundProblem 404
ConflictProblem 409
UnprocessableEntityProblem 422
TooManyRequestsProblem 429
InternalServerErrorProblem 500
import { ConflictProblem } from '@xavierdev25/rfc7807-errors';

throw new ConflictProblem({
  detail: 'A transaction with this idempotency key already exists.',
  instance: request.url, // optional; the filter fills it from the request URL
  extensions: { idempotencyKey }, // any extra members are merged into the body
});

Custom domain errors

Subclass a problem so your domain layer throws meaningful, typed errors that still serialize to RFC 7807:

import { NotFoundProblem } from '@xavierdev25/rfc7807-errors';

export class TransactionNotFoundError extends NotFoundProblem {
  constructor(id: string) {
    super({
      type: 'https://api.example.com/errors/transaction-not-found',
      detail: `Transaction with ID '${id}' was not found.`,
      extensions: { transactionId: id },
    });
  }
}

Async configuration

Rfc7807Module.forRootAsync({
  imports: [ConfigModule],
  inject: [ConfigService],
  useFactory: (config: ConfigService) => ({
    typeBaseUri: config.get('ERRORS_BASE_URI'),
    includeStackTrace: config.get('NODE_ENV') !== 'production',
  }),
});

useClass and useExisting (via Rfc7807OptionsFactory) are also supported.

What the filter handles

  1. ProblemDetailException (yours) → serialized as-is via toProblemDetail().
  2. NestJS HttpException → mapped to RFC 7807 (validation arrays become an errors member).
  3. Anything else500, with the detail masked in production to avoid leaking internals.

Options

Option Type Default Description
typeBaseUri string 'about:blank' Prefix for the type URI ({base}/{slug}).
includeStackTrace boolean false Add stackTrace to the body (never in production).
onProblem (problem, exception) => void Side-effect hook (logging/metrics).
serializer IProblemDetailSerializer JsonProblemDetailSerializer Custom output serializer (DIP).

Content type: application/problem+json. See RFC 7807.