@ogcio/fastify-error-handler 5.0.2 → 5.2.0

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.
@@ -1,34 +1,34 @@
1
- import { FastifyError, createError } from "@fastify/error";
2
- import { pino, DestinationStream } from "pino";
3
- import fastify, { FastifyInstance } from "fastify";
4
- import { initializeErrorHandler } from "../../src/index.js";
1
+ import { type FastifyError, createError } from "@fastify/error";
5
2
  import fastifySensible from "@fastify/sensible";
3
+ import fastify, { type FastifyInstance } from "fastify";
6
4
  import httpErrors from "http-errors";
5
+ import { type DestinationStream, pino } from "pino";
6
+ import { initializeErrorHandler } from "../../src/index.js";
7
7
  export const buildFastify = async (
8
- loggerDestination?: DestinationStream
8
+ loggerDestination?: DestinationStream,
9
9
  ): Promise<FastifyInstance> => {
10
10
  const server = fastify({ loggerInstance: pino({}, loggerDestination) });
11
11
  initializeErrorHandler(server as unknown as FastifyInstance);
12
12
  await server.register(fastifySensible);
13
13
  server.get("/error", async (request, _reply) => {
14
14
  const parsed = request.query as { [x: string]: unknown };
15
- const requestedStatusCode = Number(parsed["status_code"] ?? "500");
16
- const requestedMessage = String(parsed["error_message"] ?? "WHOOOPS");
15
+ const requestedStatusCode = Number(parsed.status_code ?? "500");
16
+ const requestedMessage = String(parsed.error_message ?? "WHOOOPS");
17
17
 
18
- if (!parsed["status_code"]) {
18
+ if (!parsed.status_code) {
19
19
  throw new Error(requestedMessage);
20
20
  }
21
21
 
22
22
  throw createError(
23
23
  "CUSTOM_CODE",
24
24
  requestedMessage as string,
25
- requestedStatusCode as number
25
+ requestedStatusCode as number,
26
26
  )();
27
27
  });
28
28
 
29
29
  server.get("/validation", async (request, _reply) => {
30
30
  const parsed = request.query as { [x: string]: unknown };
31
- const requestedMessage = String(parsed["error_message"] ?? "WHOOOPS");
31
+ const requestedMessage = String(parsed.error_message ?? "WHOOOPS");
32
32
 
33
33
  const error = createError(
34
34
  "CUSTOM_CODE",
@@ -56,11 +56,11 @@ export const buildFastify = async (
56
56
 
57
57
  server.get("/life-events/custom", async (request, _reply) => {
58
58
  const parsed = request.query as { [x: string]: unknown };
59
- const requestedStatusCode = Number(parsed["status_code"] ?? "500");
59
+ const requestedStatusCode = Number(parsed.status_code ?? "500");
60
60
 
61
61
  throw server.httpErrors.createError(
62
62
  requestedStatusCode as number,
63
- "message"
63
+ "message",
64
64
  );
65
65
  });
66
66
 
@@ -73,12 +73,13 @@ export const buildFastify = async (
73
73
  });
74
74
 
75
75
  server.get("/life-events/:errorCode", async (request, _reply) => {
76
- const errorCode = Number((request.params! as { errorCode: string })
77
- .errorCode);
76
+ const errorCode = request.params
77
+ ? Number((request.params as { errorCode: string }).errorCode)
78
+ : "DO NOT EXIST";
78
79
  if (!httpErrors[errorCode]) {
79
80
  throw new Error("Wrong parameter");
80
81
  }
81
-
82
+
82
83
  const errorObj = httpErrors[errorCode];
83
84
 
84
85
  throw new errorObj("Failed Correctly!");
@@ -1,4 +1,4 @@
1
- import { FastifyInstance } from "fastify";
1
+ import type { FastifyInstance } from "fastify";
2
2
  import { buildFastify } from "./build-fastify.js";
3
3
  export const DEFAULT_HOSTNAME = "localhost:80";
4
4
  export const DEFAULT_USER_AGENT = "lightMyRequest";
@@ -34,11 +34,11 @@ export const initializeServer = async (): Promise<{
34
34
  loggingDestination: TestingLoggerDestination;
35
35
  }> => {
36
36
  const loggingDestination = getTestingDestinationLogger();
37
- const server = await buildFastify(loggingDestination.loggerDestination);
37
+ const server = await buildFastify(loggingDestination.loggerDestination);
38
38
 
39
39
  return { server, loggingDestination };
40
40
  };
41
41
 
42
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
+ // biome-ignore lint/suspicious/noExplicitAny: <explanation>
43
43
  export const parseLogEntry = (logEntry: string): { [x: string]: any } =>
44
44
  JSON.parse(logEntry);
@@ -1,99 +1,101 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
1
+ import { HttpErrorClasses } from "@ogcio/shared-errors";
2
+ import httpErrors from "http-errors";
3
+ import { assert, afterEach, describe, it } from "vitest";
3
4
  import {
4
5
  DEFAULT_METHOD,
5
6
  DEFAULT_PATH,
6
7
  initializeServer,
7
8
  } from "./helpers/fastify-test-helpers.js";
8
- import httpErrors from "http-errors";
9
- import { HttpErrorClasses } from "@ogcio/shared-errors";
10
9
 
11
- test("Common error is managed as expected", async (t) => {
12
- const { server } = await initializeServer();
13
- t.after(() => server.close());
14
-
15
- const response = await server.inject({
16
- method: DEFAULT_METHOD,
17
- url: DEFAULT_PATH,
18
- query: { status_code: "500", error_message: "error message" },
19
- });
20
-
21
- assert.ok(typeof response !== "undefined");
22
- assert.equal(response?.statusCode, 500);
23
- assert.deepStrictEqual(response.json(), {
24
- code: HttpErrorClasses.ServerError,
25
- detail: "error message",
26
- requestId: "req-1",
27
- name: "FastifyError",
10
+ describe("Error management", () => {
11
+ afterEach(async () => {
12
+ const { server } = await initializeServer();
13
+ await server.close();
28
14
  });
29
- });
30
15
 
31
- test("Validation error is managed as a Life Events One", async (t) => {
32
- const { server } = await initializeServer();
33
- t.after(() => server.close());
16
+ it("manages common errors as expected", async () => {
17
+ const { server } = await initializeServer();
18
+ const response = await server.inject({
19
+ method: DEFAULT_METHOD,
20
+ url: DEFAULT_PATH,
21
+ query: { status_code: "500", error_message: "error message" },
22
+ });
34
23
 
35
- const response = await server.inject({
36
- method: DEFAULT_METHOD,
37
- url: "/validation",
38
- query: { error_message: "error message" },
24
+ assert.ok(typeof response !== "undefined");
25
+ assert.equal(response?.statusCode, 500);
26
+ assert.deepEqual(response.json(), {
27
+ code: HttpErrorClasses.ServerError,
28
+ detail: "error message",
29
+ requestId: "req-1",
30
+ name: "FastifyError",
31
+ statusCode: 500,
32
+ });
39
33
  });
40
34
 
41
- assert.ok(typeof response !== "undefined");
42
- assert.equal(response?.statusCode, 422);
43
- assert.deepStrictEqual(response.json(), {
44
- code: HttpErrorClasses.ValidationError,
45
- detail: "error message",
46
- requestId: "req-1",
47
- name: "UnprocessableEntityError",
48
- validation: [
49
- {
50
- fieldName: "the.instance.path",
51
- message: "error message",
52
- validationRule: "field",
53
- additionalInfo: {
54
- field: "one",
55
- property: "two",
35
+ it("manages validation errors as expected", async () => {
36
+ const { server } = await initializeServer();
37
+ const response = await server.inject({
38
+ method: DEFAULT_METHOD,
39
+ url: "/validation",
40
+ query: { error_message: "error message" },
41
+ });
42
+
43
+ assert.ok(typeof response !== "undefined");
44
+ assert.equal(response?.statusCode, 422);
45
+ assert.deepEqual(response.json(), {
46
+ code: HttpErrorClasses.ValidationError,
47
+ detail: "error message",
48
+ requestId: "req-1",
49
+ name: "UnprocessableEntityError",
50
+ validation: [
51
+ {
52
+ fieldName: "the.instance.path",
53
+ message: "error message",
54
+ validationRule: "field",
55
+ additionalInfo: {
56
+ field: "one",
57
+ property: "two",
58
+ },
56
59
  },
57
- },
58
- ],
60
+ ],
61
+ statusCode: 422,
62
+ });
59
63
  });
60
- });
61
64
 
62
- test("If an error with status 200 is raised, it is managed as an unknown one", async (t) => {
63
- const { server } = await initializeServer();
64
- t.after(() => server.close());
65
+ it("manages unknown errors as 500", async () => {
66
+ const { server } = await initializeServer();
67
+ const response = await server.inject({
68
+ method: DEFAULT_METHOD,
69
+ url: DEFAULT_PATH,
70
+ query: { status_code: "200", error_message: "error message" },
71
+ });
65
72
 
66
- const response = await server.inject({
67
- method: DEFAULT_METHOD,
68
- url: DEFAULT_PATH,
69
- query: { status_code: "200", error_message: "error message" },
73
+ assert.ok(typeof response !== "undefined");
74
+ assert.equal(response?.statusCode, 500);
75
+ assert.deepEqual(response.json(), {
76
+ code: HttpErrorClasses.UnknownError,
77
+ detail: "error message",
78
+ requestId: "req-1",
79
+ name: "FastifyError",
80
+ statusCode: 500,
81
+ });
70
82
  });
71
83
 
72
- assert.ok(typeof response !== "undefined");
73
- assert.equal(response?.statusCode, 500);
74
- assert.deepStrictEqual(response.json(), {
75
- code: HttpErrorClasses.UnknownError,
76
- detail: "error message",
77
- requestId: "req-1",
78
- name: "FastifyError",
79
- });
80
- });
81
-
82
- test("404 error is managed as expected", async (t) => {
83
- const { server } = await initializeServer();
84
- t.after(() => server.close());
85
-
86
- const response = await server.inject({
87
- method: DEFAULT_METHOD,
88
- url: "/this-path-does-not-exist",
89
- });
84
+ it("manages 404 errors as expected", async () => {
85
+ const { server } = await initializeServer();
86
+ const response = await server.inject({
87
+ method: DEFAULT_METHOD,
88
+ url: "/this-path-does-not-exist",
89
+ });
90
90
 
91
- assert.ok(typeof response !== "undefined");
92
- assert.equal(response?.statusCode, 404);
93
- assert.deepStrictEqual(response.json(), {
94
- code: HttpErrorClasses.NotFoundError,
95
- detail: "Route not found: /this-path-does-not-exist",
96
- requestId: "req-1",
97
- name: new httpErrors[404]("TEMP").name,
91
+ assert.ok(typeof response !== "undefined");
92
+ assert.equal(response?.statusCode, 404);
93
+ assert.deepEqual(response.json(), {
94
+ code: HttpErrorClasses.NotFoundError,
95
+ detail: "Route not found: /this-path-does-not-exist",
96
+ requestId: "req-1",
97
+ name: new httpErrors[404]("TEMP").name,
98
+ statusCode: 404,
99
+ });
98
100
  });
99
101
  });
@@ -1,11 +1,10 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
1
+ import * as sharedErrors from "@ogcio/shared-errors";
2
+ import httpErrors from "http-errors";
3
+ import { assert, afterEach, describe, it } from "vitest";
3
4
  import {
4
5
  DEFAULT_METHOD,
5
6
  initializeServer,
6
7
  } from "./helpers/fastify-test-helpers.js";
7
- import httpErrors from "http-errors";
8
- import * as sharedErrors from "@ogcio/shared-errors";
9
8
 
10
9
  const errorsProvider = [
11
10
  { errorType: httpErrors[401], expectedStatusCode: 401 },
@@ -16,67 +15,83 @@ const errorsProvider = [
16
15
  { errorType: httpErrors[502], expectedStatusCode: 502 },
17
16
  ];
18
17
 
19
- errorsProvider.forEach((errorProv) =>
20
- test(`Error is managed in the correct way - ${errorProv.errorType.name}`, async (t) => {
18
+ describe("Error management", () => {
19
+ afterEach(async () => {
21
20
  const { server } = await initializeServer();
22
- t.after(() => server.close());
23
-
24
- const errorInstance = new errorProv.errorType("message");
21
+ await server.close();
22
+ });
25
23
 
26
- const response = await server.inject({
27
- method: DEFAULT_METHOD,
28
- url: `/life-events/${errorProv.expectedStatusCode}`,
24
+ for (const errorProv of errorsProvider) {
25
+ it(`Error is managed in the correct way - ${errorProv.errorType.name}`, async (_t) => {
26
+ const { server } = await initializeServer();
27
+ await server.close();
29
28
  });
30
29
 
31
- assert.ok(typeof response !== "undefined");
32
- assert.equal(response?.statusCode, errorProv.expectedStatusCode);
33
- assert.deepStrictEqual(response.json(), {
34
- code: sharedErrors.parseHttpErrorClass(errorProv.expectedStatusCode),
35
- detail: "Failed Correctly!",
36
- requestId: "req-1",
37
- name: errorInstance.name,
38
- });
39
- })
40
- );
30
+ for (const errorProv of errorsProvider) {
31
+ it(`manages ${errorProv.errorType.name} correctly`, async () => {
32
+ const { server } = await initializeServer();
33
+ const errorInstance = new errorProv.errorType("message");
41
34
 
42
- test(`Custom error is managed based on parameters`, async (t) => {
43
- const { server } = await initializeServer();
44
- t.after(() => server.close());
35
+ const response = await server.inject({
36
+ method: DEFAULT_METHOD,
37
+ url: `/life-events/${errorProv.expectedStatusCode}`,
38
+ });
45
39
 
46
- const response = await server.inject({
47
- method: DEFAULT_METHOD,
48
- url: `/life-events/custom`,
49
- query: { status_code: "503" },
50
- });
40
+ assert.ok(typeof response !== "undefined");
41
+ assert.equal(response?.statusCode, errorProv.expectedStatusCode);
42
+ const parsedErrorClass = sharedErrors.parseHttpErrorClass(
43
+ errorProv.expectedStatusCode,
44
+ );
45
+ assert.deepEqual(response.json(), {
46
+ code: parsedErrorClass.errorClass,
47
+ detail: "Failed Correctly!",
48
+ requestId: "req-1",
49
+ name: errorInstance.name,
50
+ statusCode: parsedErrorClass.statusCode,
51
+ });
52
+ });
53
+ }
51
54
 
52
- assert.ok(typeof response !== "undefined");
53
- assert.equal(response?.statusCode, 503);
54
- assert.deepStrictEqual(response.json(), {
55
- code: sharedErrors.parseHttpErrorClass(503),
56
- detail: "message",
57
- requestId: "req-1",
58
- name: new httpErrors[503]("MOCK").name,
59
- });
60
- });
55
+ it("manages custom errors based on parameters", async () => {
56
+ const { server } = await initializeServer();
57
+ const response = await server.inject({
58
+ method: DEFAULT_METHOD,
59
+ url: "/life-events/custom",
60
+ query: { status_code: "503" },
61
+ });
61
62
 
62
- test(`Validation error is managed as expected`, async (t) => {
63
- const { server } = await initializeServer();
64
- t.after(() => server.close());
63
+ assert.ok(typeof response !== "undefined");
64
+ assert.equal(response?.statusCode, 503);
65
+ const parsedErrorClass = sharedErrors.parseHttpErrorClass(503);
66
+ assert.deepEqual(response.json(), {
67
+ code: parsedErrorClass.errorClass,
68
+ detail: "message",
69
+ requestId: "req-1",
70
+ name: new httpErrors[503]("MOCK").name,
71
+ statusCode: parsedErrorClass.statusCode,
72
+ });
73
+ });
65
74
 
66
- const response = await server.inject({
67
- method: DEFAULT_METHOD,
68
- url: `/life-events/validation`,
69
- });
75
+ it("manages validation errors as expected", async () => {
76
+ const { server } = await initializeServer();
77
+ const response = await server.inject({
78
+ method: DEFAULT_METHOD,
79
+ url: "/life-events/validation",
80
+ });
70
81
 
71
- assert.ok(typeof response !== "undefined");
72
- assert.equal(response?.statusCode, 422);
73
- assert.deepStrictEqual(response.json(), {
74
- code: sharedErrors.parseHttpErrorClass(422),
75
- detail: "message",
76
- requestId: "req-1",
77
- name: new httpErrors[422]("MOCK").name,
78
- validation: [
79
- { fieldName: "field", message: "error", validationRule: "equal" },
80
- ],
81
- });
82
+ assert.ok(typeof response !== "undefined");
83
+ assert.equal(response?.statusCode, 422);
84
+ const parsedErrorClass = sharedErrors.parseHttpErrorClass(422);
85
+ assert.deepEqual(response.json(), {
86
+ code: parsedErrorClass.errorClass,
87
+ detail: "message",
88
+ requestId: "req-1",
89
+ name: new httpErrors[422]("MOCK").name,
90
+ validation: [
91
+ { fieldName: "field", message: "error", validationRule: "equal" },
92
+ ],
93
+ statusCode: parsedErrorClass.statusCode,
94
+ });
95
+ });
96
+ }
82
97
  });
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { FastifyInstance } from "fastify";
1
+ import type { FastifyInstance } from "fastify";
2
2
  export declare const initializeErrorHandler: (server: FastifyInstance) => void;
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAM1C,eAAO,MAAM,sBAAsB,WAAY,eAAe,KAAG,IAGhE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAM/C,eAAO,MAAM,sBAAsB,WAAY,eAAe,KAAG,IAGhE,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { initializeNotFoundHandler, setupErrorHandler } from "./initialize-error-handler.js";
1
+ import { initializeNotFoundHandler, setupErrorHandler, } from "./initialize-error-handler.js";
2
2
  export const initializeErrorHandler = (server) => {
3
3
  setupErrorHandler(server);
4
4
  initializeNotFoundHandler(server);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EAClB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,MAAuB,EAAQ,EAAE;IACtE,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,yBAAyB,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,MAAuB,EAAQ,EAAE;IACtE,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,yBAAyB,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC,CAAC"}
@@ -1,5 +1,5 @@
1
- import { FastifyInstance } from "fastify";
2
- import { HttpErrorClasses, ValidationErrorData } from "@ogcio/shared-errors";
1
+ import { type HttpErrorClasses, type ValidationErrorData } from "@ogcio/shared-errors";
2
+ import type { FastifyInstance } from "fastify";
3
3
  export interface OutputHttpError {
4
4
  code: HttpErrorClasses;
5
5
  detail: string;
@@ -7,6 +7,7 @@ export interface OutputHttpError {
7
7
  name: string;
8
8
  validation?: ValidationErrorData[];
9
9
  process?: string;
10
+ statusCode: number;
10
11
  }
11
12
  export declare const setupErrorHandler: (server: FastifyInstance) => void;
12
13
  export declare const initializeNotFoundHandler: (server: FastifyInstance) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"initialize-error-handler.d.ts","sourceRoot":"","sources":["../src/initialize-error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,eAAe,EAEhB,MAAM,SAAS,CAAC;AAOjB,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EAEpB,MAAM,sBAAsB,CAAC;AAI9B,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAOD,eAAO,MAAM,iBAAiB,WAAY,eAAe,KAAG,IAyC3D,CAAC;AAIF,eAAO,MAAM,yBAAyB,WAAY,eAAe,KAAG,IAUnE,CAAC"}
1
+ {"version":3,"file":"initialize-error-handler.d.ts","sourceRoot":"","sources":["../src/initialize-error-handler.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EAEzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAEV,eAAe,EAGhB,MAAM,SAAS,CAAC;AAIjB,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAOD,eAAO,MAAM,iBAAiB,WAAY,eAAe,KAAG,IAyC3D,CAAC;AAIF,eAAO,MAAM,yBAAyB,WAAY,eAAe,KAAG,IAUnE,CAAC"}
@@ -1,7 +1,7 @@
1
- import { setLoggingContext, getLoggingContextError, LogMessages, } from "@ogcio/fastify-logging-wrapper";
1
+ import { httpErrors } from "@fastify/sensible";
2
+ import { LogMessages, getLoggingContextError, setLoggingContext, } from "@ogcio/fastify-logging-wrapper";
2
3
  import { parseHttpErrorClass, } from "@ogcio/shared-errors";
3
4
  import { isHttpError } from "http-errors";
4
- import { httpErrors } from "@fastify/sensible";
5
5
  // The error handler below is the same as the original one in Fastify,
6
6
  // just without unwanted log entries
7
7
  // I've opened an issue to fastify to ask them if we could avoid logging
@@ -27,7 +27,7 @@ export const setupErrorHandler = (server) => {
27
27
  res.statusCode = statusCode;
28
28
  reply.statusCode = res.statusCode;
29
29
  };
30
- server.setErrorHandler(function (error, request, reply) {
30
+ server.setErrorHandler((error, request, reply) => {
31
31
  if (isHttpError(error)) {
32
32
  manageHttpError(error, request, reply);
33
33
  return;
@@ -77,11 +77,13 @@ const getValidationFromFastifyError = (validationInput) => {
77
77
  return { validation: output };
78
78
  };
79
79
  const getResponseFromFastifyError = (error, request) => {
80
+ const errorDetails = parseHttpErrorClass(error.statusCode);
80
81
  const output = {
81
- code: parseHttpErrorClass(error.statusCode),
82
+ code: errorDetails.errorClass,
82
83
  detail: error.message,
83
84
  requestId: request.id,
84
85
  name: error.name,
86
+ statusCode: errorDetails.statusCode,
85
87
  };
86
88
  if (error.validation && error.validation.length > 0) {
87
89
  output.validation = getValidationFromFastifyError(error.validation).validation;
@@ -91,12 +93,14 @@ const getResponseFromFastifyError = (error, request) => {
91
93
  const manageHttpError = (error, request, reply) => {
92
94
  reply.raw.statusCode = error.statusCode;
93
95
  reply.statusCode = error.statusCode;
96
+ const errorDetails = parseHttpErrorClass(error.statusCode);
94
97
  const errorResponse = {
95
- code: parseHttpErrorClass(error.statusCode),
98
+ code: errorDetails.errorClass,
96
99
  detail: error.message,
97
100
  requestId: request.id,
98
101
  name: error.name,
99
102
  process: error.errorProcess,
103
+ statusCode: errorDetails.statusCode,
100
104
  };
101
105
  let validationErrors = error.validationErrors && error.validationErrors.length > 0
102
106
  ? error.validationErrors
@@ -107,6 +111,7 @@ const manageHttpError = (error, request, reply) => {
107
111
  if (validationErrors) {
108
112
  errorResponse.validation = validationErrors;
109
113
  }
114
+ console.log({ errorResponse, errorDetails });
110
115
  reply.status(error.statusCode).send(errorResponse);
111
116
  };
112
117
  const toOutputHttpValidationError = (error) => {
@@ -1 +1 @@
1
- {"version":3,"file":"initialize-error-handler.js","sourceRoot":"","sources":["../src/initialize-error-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"initialize-error-handler.js","sourceRoot":"","sources":["../src/initialize-error-handler.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@ogcio/fastify-error-handler",
3
- "version": "5.0.2",
3
+ "version": "5.2.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
7
7
  "scripts": {
8
8
  "build": "rm -rf dist tsconfig.prod.tsbuildinfo tsconfig.tsbuildinfo && tsc -p tsconfig.prod.json",
9
- "test": "tap --jobs=1 --allow-incomplete-coverage __tests__/**/*.test.ts"
9
+ "test": "vitest run --coverage --outputFile=results.xml",
10
+ "prepublishOnly": "npm i && npm run build && npm run test"
10
11
  },
11
12
  "keywords": [],
12
13
  "author": {
@@ -17,8 +18,8 @@
17
18
  "description": "Normalize the error handling of errors with related logs",
18
19
  "dependencies": {
19
20
  "@ogcio/fastify-logging-wrapper": "^5.0.2",
20
- "@ogcio/shared-errors": "^1.0.0",
21
- "fastify": "^5.0.0"
21
+ "@ogcio/shared-errors": "^1.1.0",
22
+ "fastify": "^5.1.0"
22
23
  },
23
24
  "devDependencies": {
24
25
  "@types/http-errors": "^2.0.4"
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { FastifyInstance } from "fastify";
1
+ import type { FastifyInstance } from "fastify";
2
2
  import {
3
3
  initializeNotFoundHandler,
4
- setupErrorHandler
4
+ setupErrorHandler,
5
5
  } from "./initialize-error-handler.js";
6
6
 
7
7
  export const initializeErrorHandler = (server: FastifyInstance): void => {
@@ -1,22 +1,22 @@
1
+ import { type HttpError, httpErrors } from "@fastify/sensible";
1
2
  import {
2
- FastifyError,
3
- FastifyRequest,
4
- FastifyInstance,
5
- FastifyReply,
6
- } from "fastify";
7
- import { FastifySchemaValidationError } from "fastify/types/schema.js";
8
- import {
9
- setLoggingContext,
10
- getLoggingContextError,
11
3
  LogMessages,
4
+ getLoggingContextError,
5
+ setLoggingContext,
12
6
  } from "@ogcio/fastify-logging-wrapper";
13
7
  import {
14
- HttpErrorClasses,
15
- ValidationErrorData,
8
+ type HttpErrorClasses,
9
+ type ValidationErrorData,
16
10
  parseHttpErrorClass,
17
11
  } from "@ogcio/shared-errors";
12
+ import type {
13
+ FastifyError,
14
+ FastifyInstance,
15
+ FastifyReply,
16
+ FastifyRequest,
17
+ } from "fastify";
18
+ import type { FastifySchemaValidationError } from "fastify/types/schema.js";
18
19
  import { isHttpError } from "http-errors";
19
- import { HttpError, httpErrors } from "@fastify/sensible";
20
20
 
21
21
  export interface OutputHttpError {
22
22
  code: HttpErrorClasses;
@@ -25,6 +25,7 @@ export interface OutputHttpError {
25
25
  name: string;
26
26
  validation?: ValidationErrorData[];
27
27
  process?: string;
28
+ statusCode: number;
28
29
  }
29
30
 
30
31
  // The error handler below is the same as the original one in Fastify,
@@ -39,7 +40,7 @@ export const setupErrorHandler = (server: FastifyInstance): void => {
39
40
  status?: number;
40
41
  statusCode?: number;
41
42
  },
42
- reply: FastifyReply
43
+ reply: FastifyReply,
43
44
  ) => {
44
45
  const res = reply.raw;
45
46
  let statusCode = res.statusCode;
@@ -59,7 +60,7 @@ export const setupErrorHandler = (server: FastifyInstance): void => {
59
60
  reply.statusCode = res.statusCode;
60
61
  };
61
62
 
62
- server.setErrorHandler(function (error, request, reply) {
63
+ server.setErrorHandler((error, request, reply) => {
63
64
  if (isHttpError(error)) {
64
65
  manageHttpError(error, request, reply);
65
66
  return;
@@ -90,7 +91,7 @@ export const initializeNotFoundHandler = (server: FastifyInstance): void => {
90
91
  };
91
92
 
92
93
  const getValidationFromFastifyError = (
93
- validationInput: FastifySchemaValidationError[]
94
+ validationInput: FastifySchemaValidationError[],
94
95
  ): { validation: ValidationErrorData[] } => {
95
96
  const output: ValidationErrorData[] = [];
96
97
 
@@ -121,17 +122,20 @@ const getValidationFromFastifyError = (
121
122
 
122
123
  const getResponseFromFastifyError = (
123
124
  error: FastifyError,
124
- request: FastifyRequest
125
+ request: FastifyRequest,
125
126
  ): OutputHttpError => {
127
+ const errorDetails = parseHttpErrorClass(error.statusCode);
128
+
126
129
  const output: OutputHttpError = {
127
- code: parseHttpErrorClass(error.statusCode),
130
+ code: errorDetails.errorClass,
128
131
  detail: error.message,
129
132
  requestId: request.id,
130
133
  name: error.name,
134
+ statusCode: errorDetails.statusCode,
131
135
  };
132
136
  if (error.validation && error.validation.length > 0) {
133
137
  output.validation = getValidationFromFastifyError(
134
- error.validation
138
+ error.validation,
135
139
  ).validation;
136
140
  }
137
141
 
@@ -141,16 +145,18 @@ const getResponseFromFastifyError = (
141
145
  const manageHttpError = (
142
146
  error: HttpError,
143
147
  request: FastifyRequest,
144
- reply: FastifyReply
148
+ reply: FastifyReply,
145
149
  ): void => {
146
150
  reply.raw.statusCode = error.statusCode;
147
151
  reply.statusCode = error.statusCode;
152
+ const errorDetails = parseHttpErrorClass(error.statusCode);
148
153
  const errorResponse: OutputHttpError = {
149
- code: parseHttpErrorClass(error.statusCode),
154
+ code: errorDetails.errorClass,
150
155
  detail: error.message,
151
156
  requestId: request.id,
152
157
  name: error.name,
153
158
  process: error.errorProcess,
159
+ statusCode: errorDetails.statusCode,
154
160
  };
155
161
  let validationErrors =
156
162
  error.validationErrors && error.validationErrors.length > 0
@@ -163,7 +169,7 @@ const manageHttpError = (
163
169
  if (validationErrors) {
164
170
  errorResponse.validation = validationErrors;
165
171
  }
166
-
172
+ console.log({ errorResponse, errorDetails });
167
173
  reply.status(error.statusCode).send(errorResponse);
168
174
  };
169
175
 
@@ -175,6 +181,6 @@ const toOutputHttpValidationError = (error: FastifyError): HttpError => {
175
181
  return httpErrors.createError(
176
182
  422,
177
183
  error.message,
178
- getValidationFromFastifyError(error.validation)
184
+ getValidationFromFastifyError(error.validation),
179
185
  );
180
186
  };
@@ -0,0 +1,19 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ reporters: "default",
6
+ coverage: {
7
+ reporter: ["text", "cobertura"],
8
+ provider: "istanbul",
9
+ },
10
+ include: [
11
+ "**/@(test?(s)|__test?(s)__)/**/*.test.@(js|cjs|mjs|tap|cts|jsx|mts|ts|tsx)",
12
+ "**/*.@(test?(s)|spec).@(js|cjs|mjs|tap|cts|jsx|mts|ts|tsx)",
13
+ "**/test?(s).@(js|cjs|mjs|tap|cts|jsx|mts|ts|tsx)",
14
+ ],
15
+ exclude: ["**/@(fixture*(s)|dist|node_modules)/**"],
16
+ maxConcurrency: 1,
17
+ testTimeout: 30000, // Timeout in milliseconds (30 seconds)
18
+ },
19
+ });