Skip to content

Commit 0c49f78

Browse files
authored
Capture server errors in NestJS (#53)
* Add test * Add NestJS exceptions filter
1 parent 7267e75 commit 0c49f78

File tree

8 files changed

+45
-8
lines changed

8 files changed

+45
-8
lines changed

src/nestjs/index.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,24 @@
1+
import { ArgumentsHost, Catch, INestApplication } from "@nestjs/common";
2+
import { BaseExceptionFilter } from "@nestjs/core";
3+
import { Response } from "express";
4+
5+
import type { ApitallyConfig } from "../common/types.js";
6+
import { useApitally as useApitallyExpress } from "../express/index.js";
17
export type { ApitallyConsumer } from "../common/types.js";
2-
export { useApitally } from "../express/index.js";
8+
9+
export const useApitally = (app: INestApplication, config: ApitallyConfig) => {
10+
const httpAdapter = app.getHttpAdapter();
11+
const expressInstance = httpAdapter.getInstance();
12+
useApitallyExpress(expressInstance, config);
13+
app.useGlobalFilters(new AllExceptionsFilter(httpAdapter));
14+
};
15+
16+
@Catch()
17+
class AllExceptionsFilter extends BaseExceptionFilter {
18+
catch(exception: unknown, host: ArgumentsHost) {
19+
const ctx = host.switchToHttp();
20+
const res = ctx.getResponse<Response>();
21+
res.locals.serverError = exception;
22+
super.catch(exception, host);
23+
}
24+
}

tests/express/app.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ testCases.forEach(({ name, getApp }) => {
4646
await appTest.get("/error").expect(500);
4747

4848
const requests = client.requestCounter.getAndResetRequests();
49-
const serverErrors = client.serverErrorCounter.getAndResetServerErrors();
5049
expect(requests.length).toBe(4);
5150
expect(
5251
requests.some(
@@ -76,6 +75,8 @@ testCases.forEach(({ name, getApp }) => {
7675
expect(
7776
requests.some((r) => r.status_code === 500 && r.request_count === 1),
7877
).toBe(true);
78+
79+
const serverErrors = client.serverErrorCounter.getAndResetServerErrors();
7980
expect(serverErrors.length).toBe(1);
8081
expect(
8182
serverErrors.some(

tests/fastify/app.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ describe("Plugin for Fastify", () => {
3030
await appTest.get("/error").expect(500);
3131

3232
const requests = client.requestCounter.getAndResetRequests();
33-
const serverErrors = client.serverErrorCounter.getAndResetServerErrors();
3433
expect(requests.length).toBe(4);
3534
expect(
3635
requests.some(
@@ -60,6 +59,8 @@ describe("Plugin for Fastify", () => {
6059
expect(
6160
requests.some((r) => r.status_code === 500 && r.request_count === 1),
6261
).toBe(true);
62+
63+
const serverErrors = client.serverErrorCounter.getAndResetServerErrors();
6364
expect(serverErrors.length).toBe(1);
6465
expect(
6566
serverErrors.some(

tests/hono/app.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ describe("Middleware for Hono", () => {
5252
expect(res.status).toBe(500);
5353

5454
const requests = client.requestCounter.getAndResetRequests();
55-
const serverErrors = client.serverErrorCounter.getAndResetServerErrors();
5655
expect(requests.length).toBe(5);
5756
expect(
5857
requests.some(
@@ -89,6 +88,8 @@ describe("Middleware for Hono", () => {
8988
expect(
9089
requests.some((r) => r.status_code === 500 && r.request_count === 1),
9190
).toBe(true);
91+
92+
const serverErrors = client.serverErrorCounter.getAndResetServerErrors();
9293
expect(serverErrors.length).toBe(1);
9394
expect(
9495
serverErrors.some(

tests/koa/app.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ testCases.forEach(({ name, router, getApp }) => {
4848
consoleSpy.mockRestore();
4949

5050
const requests = client.requestCounter.getAndResetRequests();
51-
const serverErrors = client.serverErrorCounter.getAndResetServerErrors();
5251
expect(requests.length).toBe(3);
5352
expect(
5453
requests.some(
@@ -73,6 +72,8 @@ testCases.forEach(({ name, router, getApp }) => {
7372
),
7473
).toBe(true);
7574
expect(requests.some((r) => r.status_code === 500)).toBe(true);
75+
76+
const serverErrors = client.serverErrorCounter.getAndResetServerErrors();
7677
expect(serverErrors.length).toBe(1);
7778
expect(
7879
serverErrors.some(

tests/nestjs/app.controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,6 @@ export class AppController {
4040

4141
@Get("/error")
4242
getError() {
43-
throw new Error("Error");
43+
throw new Error("test");
4444
}
4545
}

tests/nestjs/app.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ describe("Middleware for NestJS", () => {
5050
expect(
5151
requests.some((r) => r.status_code === 500 && r.request_count === 1),
5252
).toBe(true);
53+
54+
const serverErrors = client.serverErrorCounter.getAndResetServerErrors();
55+
expect(serverErrors.length).toBe(1);
56+
expect(
57+
serverErrors.some(
58+
(e) =>
59+
e.type === "Error" &&
60+
e.msg === "test" &&
61+
e.traceback &&
62+
e.error_count === 1,
63+
),
64+
).toBe(true);
5365
});
5466

5567
it("Validation error logger", async () => {

tests/nestjs/app.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ export async function getApp() {
1010
providers: [],
1111
}).compile();
1212
const app = moduleFixture.createNestApplication();
13-
const expressInstance = app.getHttpAdapter().getInstance();
1413

15-
useApitally(expressInstance, {
14+
useApitally(app, {
1615
clientId: CLIENT_ID,
1716
env: ENV,
1817
appVersion: "1.2.3",

0 commit comments

Comments
 (0)