add test for error handling

This commit is contained in:
StarAppeal
2025-09-18 21:45:57 +02:00
parent c7d4454359
commit 075fafa122
2 changed files with 92 additions and 20 deletions
+42 -18
View File
@@ -1,17 +1,18 @@
import express from "express";
import { ExtendedWebSocketServer } from "./websocket";
import { RestWebSocket } from "./rest/restWebSocket";
import { RestUser } from "./rest/restUser";
import { authenticateJwt } from "./rest/middleware/authenticateJwt";
import { JwtTokenPropertiesExtractor } from "./rest/jwtTokenPropertiesExtractor";
import {ExtendedWebSocketServer} from "./websocket";
import {RestWebSocket} from "./rest/restWebSocket";
import {RestUser} from "./rest/restUser";
import {authenticateJwt} from "./rest/middleware/authenticateJwt";
import {JwtTokenPropertiesExtractor} from "./rest/jwtTokenPropertiesExtractor";
import cors from "cors";
import { SpotifyTokenGenerator } from "./rest/spotifyTokenGenerator";
import { RestAuth } from "./rest/auth";
import { config } from "./config";
import {SpotifyTokenGenerator} from "./rest/spotifyTokenGenerator";
import {RestAuth} from "./rest/auth";
import {config} from "./config";
import cookieParser from 'cookie-parser';
import { authLimiter, spotifyLimiter } from "./rest/middleware/rateLimit";
import { cookieJwtAuth } from "./rest/middleware/cookieAuth";
import { UserService } from "./db/services/db/UserService";
import {authLimiter, spotifyLimiter} from "./rest/middleware/rateLimit";
import {cookieJwtAuth} from "./rest/middleware/cookieAuth";
import {UserService} from "./db/services/db/UserService";
import {randomUUID} from "crypto";
export async function startServer() {
const app = express();
@@ -36,8 +37,8 @@ export async function startServer() {
next();
});
app.use(express.json({ limit: "2mb" }));
app.get("/api/healthz", (_req, res) => res.status(200).send({ status: "ok" }));
app.use(express.json({limit: "2mb"}));
app.get("/api/healthz", (_req, res) => res.status(200).send({status: "ok"}));
console.log("Connecting to database and creating UserService...");
const userService = await UserService.create();
@@ -67,10 +68,33 @@ export async function startServer() {
);
app.use((err: any, _req: express.Request, res: express.Response, _next: express.NextFunction) => {
console.error(err);
res
.status(err?.status || 500)
.send({ ok: false, data: {}, error: err?.message || "Internal Server Error" });
const errorId = randomUUID();
console.error(`Error ID: ${errorId} | Status: ${err?.status || 500} | Message: ${err?.message}`);
console.error(`Stack Trace [${errorId}]:`, err.stack);
const statusCode = err?.status || 500;
let errorMessage = err?.message || "Internal Server Error";
let errorResponse: { ok: boolean; data: { error: string; errorId?: string } } = {
ok: false,
data: {
error: errorMessage,
}
};
if (statusCode >= 500) {
errorMessage = "An unexpected error occurred.";
errorResponse = {
ok: false,
data: {
error: errorMessage,
errorId: errorId,
}
};
}
res.status(statusCode).send(errorResponse);
});
process.on("SIGTERM", () => {
@@ -81,7 +105,7 @@ export async function startServer() {
});
});
return { app, server };
return {app, server};
}
if (process.env.NODE_ENV !== 'test') {
+50 -2
View File
@@ -1,6 +1,6 @@
import { describe, it, expect, vi, beforeAll, afterAll, beforeEach } from "vitest";
import request from "supertest";
import express from "express";
import express, {Router} from "express";
import http from "http";
import { authLimiter } from "../src/rest/middleware/rateLimit";
@@ -28,6 +28,30 @@ vi.mock("../src/rest/middleware/rateLimit", async (importOriginal) => {
};
});
// feels kinda hacky tbh
vi.mock("../src/rest/auth", () => {
const RestAuth = vi.fn().mockImplementation(() => {
return {
createRouter: () => {
const router = Router();
router.get("/test-500-error", (_req, _res, _next) => {
throw new Error("Simulated internal server error!");
});
router.get("/test-400-error", (_req, _res, next) => {
const clientError = new Error("Simulated client error.");
(clientError as any).status = 400;
next(clientError);
});
return router;
}
};
});
return { RestAuth };
});
let app: express.Application;
let server: http.Server;
@@ -93,4 +117,28 @@ describe("Express App Integration Test", () => {
it("should return a 404 for an unknown route", async () => {
await request(app).get("/api/this-route-does-not-exist").expect(404);
});
});
});
describe("Error Handling Middleware", () => {
it("should handle a 500 internal server error and return a generic message with an errorId", async () => {
const response = await request(app)
.get("/api/auth/test-500-error")
.expect(500);
expect(response.body.ok).toBe(false);
expect(response.body.data.error).toBe("An unexpected error occurred.");
expect(response.body.data.errorId).toBeDefined();
expect(typeof response.body.data.errorId).toBe("string");
});
it("should handle a 400 client error and return the specific message without an errorId", async () => {
const response = await request(app)
.get("/api/auth/test-400-error")
.expect(400);
expect(response.body.ok).toBe(false);
expect(response.body.data.error).toBe("Simulated client error.");
expect(response.body.data.errorId).toBeUndefined();
});
});