add test for error handling
This commit is contained in:
+42
-18
@@ -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') {
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user