diff --git a/packages/backend-openapi-utils/src/proxy/setup.ts b/packages/backend-openapi-utils/src/proxy/setup.ts index ed35a0d3c5..0e47e4a5d6 100644 --- a/packages/backend-openapi-utils/src/proxy/setup.ts +++ b/packages/backend-openapi-utils/src/proxy/setup.ts @@ -58,14 +58,40 @@ export class Proxy { this.express.server = server; } - stop() { + async stop() { if (Object.keys(this.#openRequests).length > 0) { throw new Error('There are still open requests'); } - this.server.stop(); + if (!this.express.server) { + throw new Error( + 'Proxy server was not initialized with an express server', + ); + } + const results = await Promise.allSettled([ + this.server.stop(), - // If this isn't expressly closed, it will cause a jest memory leak warning. - this.express.server?.close(); + // If this isn't expressly closed, it will cause a jest memory leak warning. + new Promise((resolve, reject) => { + this.express.server?.close(err => { + if (err) { + reject(err); + } else { + resolve(undefined); + } + }); + }), + ]); + if (results.some(result => result.status === 'rejected')) { + const errors = results + .filter( + (result): result is PromiseRejectedResult => + result.status === 'rejected', + ) + .map(result => result.reason); + throw new Error( + `Failed to stop proxy server: ${errors.map(e => e.message).join(', ')}`, + ); + } } get url() { diff --git a/packages/backend-openapi-utils/src/testUtils.ts b/packages/backend-openapi-utils/src/testUtils.ts index 88bb3db5bf..afb431c75b 100644 --- a/packages/backend-openapi-utils/src/testUtils.ts +++ b/packages/backend-openapi-utils/src/testUtils.ts @@ -16,8 +16,9 @@ import { Express } from 'express'; import { Server } from 'node:http'; import { Proxy } from './proxy/setup'; +import { randomUUID } from 'node:crypto'; -const proxiesToCleanup: Proxy[] = []; +const proxiesToCleanup: Record = {}; /** * !!! THIS CURRENTLY ONLY SUPPORTS SUPERTEST !!! @@ -29,7 +30,8 @@ const proxiesToCleanup: Proxy[] = []; */ export async function wrapServer(app: Express): Promise { const proxy = new Proxy(); - proxiesToCleanup.push(proxy); + const proxyId = randomUUID(); + proxiesToCleanup[proxyId] = proxy; await proxy.setup(); const server = app.listen(proxy.forwardTo.port); @@ -48,10 +50,11 @@ function registerHooks() { } registered = true; - afterAll(() => { - for (const proxy of proxiesToCleanup) { - proxy.stop(); - } + afterAll(async () => { + const stopPromises = Object.entries(proxiesToCleanup).map(([key, proxy]) => + proxy.stop().finally(() => delete proxiesToCleanup[key]), + ); + await Promise.allSettled(stopPromises); }); }