Skip to main content
Owner: Backend Engineering Last reviewed: 2026-09-27 Next review: 2026-12-27

Request flow

Route validation and services throw exceptions. ExceptionsModule.forRoot() registers the single global AppExceptionsFilter, which delegates serialization to AllExceptionsFilter. Feature modules register AppException mappings through ExceptionsModule.forFeature(). Do not register another catch-all filter in main.ts: doing so previously bypassed those mappings. All HTTP failures have statusCode, a readable string message, data (details or null), and error. DTO validation returns 400, errorCode: 10000, and the individual messages in data and reasons. Native Nest message arrays become a joined summary plus a data array. Zod errors retain their field/message/code objects in errors and data. Expired-token responses retain status 498, application code 10198 and optional expiredAt. Cooldown and account-linking metadata is preserved. The public integration guide is in the docs repository at api-reference/errors.mdx. Frontends can display message directly. Clients that turn responses into plain Error objects must retain structured response data separately if they need field errors or cooldown UI.

Writing service errors

  • Use BadRequestException for invalid requests, ForbiddenException for denied access and NotFoundException for missing resources. Do not throw a generic Error for expected user-facing failures.
  • Preserve typed exceptions through catch blocks. Do not convert every failure to 400 or 500, or infer status from words in an error message.
  • Register custom AppException mappings in the owning module. An unmapped application exception remains an internal failure.
  • Keep unexpected infrastructure failures as server errors. Do not expose raw provider errors, SQL, credentials or stacks in an HttpException response. The filter logs unexpected failures and sends a generic message.
  • Validators must handle missing and incorrectly typed input without throwing. The password validator now checks the type before reading its length.
The audit corrected error classification in room/notification access, file linking, review deletion, search limits, category product types, queue lookup and webhook recovery. Analytics and session-room catches preserve existing HTTP errors. Student interest-group and search-index failures no longer masquerade as invalid input. Payment processing and webhook acknowledgement semantics were not changed.

Verification

From server, run:
The HTTP suite binds a temporary loopback port and uses the actual global filter registration. Unit tests cover password values of different types, valid input, Zod errors, exception mappings, token/cooldown metadata, safe internal errors and domain errors without unintended writes. Manual checks on the configured test environment:
  1. Submit a weak, missing and mismatched password to registration, reset-password and change-password routes. Expect 400 and a readable message in the frontend.
  2. Submit valid data to confirm successful behavior is unchanged.
  3. Exercise invalid authentication, expired tokens, forbidden operations, missing resources, cooldowns and rate limits; verify status and metadata.
  4. Trigger a controlled upstream outage in a test environment. Expect a server error without internal details, and a useful server log.
During this audit, the broader selected regression suites had 47 failures that also reproduced against the unchanged HEAD: 16 auth mock failures and 31 missing provider/mock failures across InstantDB, OpenSearch and reviews. Those legacy suite fixtures need separate repair; they are not evidence that live flows pass.