@bymax-one/nest-core 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -11,6 +11,22 @@ heading here.
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [1.2.1] - 2026-08-08
15
+
16
+ A patch: the envelope fix below changes a response status for a class of client errors, without
17
+ touching the module's API or any option.
18
+
19
+ ### Fixed
20
+
21
+ - **An error carrying a 4xx status it marked exposable keeps that status, instead of collapsing to 500.** Express's body pipeline throws `http-errors` instances before any handler runs — a payload
22
+ past the limit is `PayloadTooLargeError` (413), malformed JSON is a `SyntaxError` (400), an
23
+ unsupported media type is 415. None is a Nest `HttpException`, so each reached the generic
24
+ 500 collapse: a client that sent too large a body, or malformed JSON, was told the server failed,
25
+ and a monitor counted a 5xx for a request that never entered the application. The filter now reads
26
+ the `expose: true` flag and the numeric status these carry and honours it — restricted to the 4xx
27
+ range, because a self-reported 5xx is still a server failure whose account of itself must not
28
+ surface, so it stays a generic 500.
29
+
14
30
  ## [1.2.0] - 2026-08-08
15
31
 
16
32
  Both entries change what a caller receives, which is why this is a minor rather than a patch: an
@@ -301,5 +317,6 @@ have regressed from. They are kept because the reasoning is worth having.
301
317
  [1.0.1]: https://github.com/bymaxone/nest-core/compare/v1.0.0...v1.0.1
302
318
  [1.0.0]: https://github.com/bymaxone/nest-core/releases/tag/v1.0.0
303
319
  [1.1.1]: https://github.com/bymaxone/nest-core/compare/v1.1.0...v1.1.1
320
+ [1.2.1]: https://github.com/bymaxone/nest-core/compare/v1.2.0...v1.2.1
304
321
  [1.2.0]: https://github.com/bymaxone/nest-core/compare/v1.1.1...v1.2.0
305
- [Unreleased]: https://github.com/bymaxone/nest-core/compare/v1.2.0...HEAD
322
+ [Unreleased]: https://github.com/bymaxone/nest-core/compare/v1.2.1...HEAD
package/dist/index.cjs CHANGED
@@ -310,6 +310,23 @@ function extractExplicitDetails(carrier) {
310
310
  const details = carrier.details;
311
311
  return typeof details === "object" && details !== null ? details : void 0;
312
312
  }
313
+ var CLIENT_ERROR_MIN2 = 400;
314
+ var CLIENT_ERROR_MAX2 = 500;
315
+ function resolveExposedClientError(exception) {
316
+ if (typeof exception !== "object" || exception === null) {
317
+ return void 0;
318
+ }
319
+ const candidate = exception;
320
+ if (candidate.expose !== true) {
321
+ return void 0;
322
+ }
323
+ const status = Number.isInteger(candidate.status) ? candidate.status : candidate.statusCode;
324
+ if (typeof status !== "number" || !Number.isInteger(status) || status < CLIENT_ERROR_MIN2 || status >= CLIENT_ERROR_MAX2) {
325
+ return void 0;
326
+ }
327
+ const message = exception instanceof Error ? exception.message : "";
328
+ return { status, message: message === "" ? INTERNAL_ERROR_MESSAGE : message };
329
+ }
313
330
  function isValidationResponse(response) {
314
331
  return typeof response === "object" && response !== null && "message" in response && Array.isArray(response.message);
315
332
  }
@@ -424,6 +441,15 @@ exports.BymaxExceptionFilter = class BymaxExceptionFilter {
424
441
  if (exception instanceof common.HttpException) {
425
442
  return this.mapHttpException(exception, context);
426
443
  }
444
+ const exposed = resolveExposedClientError(exception);
445
+ if (exposed !== void 0) {
446
+ return this.toEnvelope(
447
+ exposed.status,
448
+ codeForStatus(exposed.status),
449
+ exposed.message,
450
+ context
451
+ );
452
+ }
427
453
  try {
428
454
  this.onUnexpectedError(exception, context);
429
455
  } catch {
package/dist/index.mjs CHANGED
@@ -308,6 +308,23 @@ function extractExplicitDetails(carrier) {
308
308
  const details = carrier.details;
309
309
  return typeof details === "object" && details !== null ? details : void 0;
310
310
  }
311
+ var CLIENT_ERROR_MIN2 = 400;
312
+ var CLIENT_ERROR_MAX2 = 500;
313
+ function resolveExposedClientError(exception) {
314
+ if (typeof exception !== "object" || exception === null) {
315
+ return void 0;
316
+ }
317
+ const candidate = exception;
318
+ if (candidate.expose !== true) {
319
+ return void 0;
320
+ }
321
+ const status = Number.isInteger(candidate.status) ? candidate.status : candidate.statusCode;
322
+ if (typeof status !== "number" || !Number.isInteger(status) || status < CLIENT_ERROR_MIN2 || status >= CLIENT_ERROR_MAX2) {
323
+ return void 0;
324
+ }
325
+ const message = exception instanceof Error ? exception.message : "";
326
+ return { status, message: message === "" ? INTERNAL_ERROR_MESSAGE : message };
327
+ }
311
328
  function isValidationResponse(response) {
312
329
  return typeof response === "object" && response !== null && "message" in response && Array.isArray(response.message);
313
330
  }
@@ -422,6 +439,15 @@ var BymaxExceptionFilter = class {
422
439
  if (exception instanceof HttpException) {
423
440
  return this.mapHttpException(exception, context);
424
441
  }
442
+ const exposed = resolveExposedClientError(exception);
443
+ if (exposed !== void 0) {
444
+ return this.toEnvelope(
445
+ exposed.status,
446
+ codeForStatus(exposed.status),
447
+ exposed.message,
448
+ context
449
+ );
450
+ }
425
451
  try {
426
452
  this.onUnexpectedError(exception, context);
427
453
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bymax-one/nest-core",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Zero-dependency NestJS 11 application foundation kit: error-envelope exception filter, request-timing interceptor, pagination helpers, health endpoints with indicator discovery, an optional Prometheus metrics endpoint with a contribution contract, OpenAPI documents in development, and OpenTelemetry trace correlation.",
5
5
  "author": "Bymax One <support@bymax.one>",
6
6
  "license": "MIT",