Skip to content

fix(core): Serialize errorCode for plain HttpException responses - #17627

Merged
kamilmysliwiec merged 1 commit into
nestjs:masterfrom
hktitof:fix/exceptions-errorcode-plain-httpexception
Aug 30, 2026
Merged

fix(core): Serialize errorCode for plain HttpException responses#17627
kamilmysliwiec merged 1 commit into
nestjs:masterfrom
hktitof:fix/exceptions-errorcode-plain-httpexception

Conversation

@hktitof

@hktitof hktitof commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Other... Please describe:

What is the current behavior?

a plain HttpException built with a string body and an errorCode option sets exception.errorCode, but BaseExceptionFilter rebuilds the response body from getResponse() and drops the code, so these two behave differently today:

// built-in exceptions (fixed by #17615): errorCode IS in the body
throw new BadRequestException('Password is too weak', { errorCode: 'WEAK_PASSWORD' });
// -> { message, error, statusCode, errorCode }

// plain HttpException: errorCode is LOST
throw new HttpException('Forbidden', 403, { errorCode: 'FORBIDDEN_ERR' });
// -> { statusCode: 403, message: 'Forbidden' }  <- errorCode missing

this is the sibling gap the author of #17615 called out in that PR: "A plain new HttpException('Forbidden', 403, { errorCode }) is unchanged, since its response is a bare string and BaseExceptionFilter rebuilds the body itself... I can add it here if you want it"

Issue Number: N/A (no dedicated issue, this completes the follow-up offered in #17615)

What is the new behavior?

BaseExceptionFilter keeps errorCode in the rebuilt body when the exception response is a bare string:

{
  "statusCode": 403,
  "message": "Forbidden",
  "errorCode": "FORBIDDEN_ERR"
}

nothing changes when no errorCode is set, and object responses are still passed through verbatim

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

verified: 2 new cases in exceptions-handler.spec.ts, the errorCode one fails without this change, the no-errorCode one asserts the body shape stays untouched, full exceptions suites pass (26 files / 209 tests), prettier + oxlint clean

A plain HttpException constructed with a string body and an errorCode
option sets exception.errorCode but BaseExceptionFilter rebuilds the
response body from getResponse() and drops the errorCode, so the
serialized body is {statusCode:403,message:Forbidden} instead of
including errorCode.

The built-in exceptions path was fixed by nestjs#17615 (forwards
httpExceptionOptions.errorCode into createBody); this closes the same
gap for the bare-string path in @nestjs/core, as offered as a follow-up
in that PR. Object responses are preserved verbatim and the no-errorCode
case is unchanged.

Tests: two new cases in exceptions-handler.spec.ts; the errorCode one
fails without this change.

Signed-off-by: Abdel <hktitof@gmail.com>
@kamilmysliwiec
kamilmysliwiec merged commit a9bf20b into nestjs:master Aug 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants