Skip to content

Commit bb07719

Browse files
authored
Add ThrowableResponse (#42)
2 parents 3493ba7 + 3d10f97 commit bb07719

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

src/Server.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import packageJson from "../package.json" with {type: "json"};
44
import {Request} from "./Request.js";
55
import {EmptyResponse} from "./response/index.js";
66
import {Response} from "./response/Response.js";
7+
import {ThrowableResponse} from "./response/ThrowableResponse.js";
78
import {RouteRegistry} from "./routing/RouteRegistry.js";
89
import {ServerErrorRegistry} from "./ServerErrorRegistry.js";
910

@@ -82,9 +83,13 @@ class Server extends EventEmitter<Server.Events> {
8283
this.errors._get(ServerErrorRegistry.ErrorCodes.BAD_URL, null)._send(res, this);
8384
return;
8485
}
86+
8587
if (e instanceof Request.SocketClosedError)
8688
return;
87-
throw e;
89+
90+
this.emit("error", e as any);
91+
this.errors._get(ServerErrorRegistry.ErrorCodes.INTERNAL, null)._send(res, this);
92+
return;
8893
}
8994

9095
for (const [key, value] of this.globalHeaders)
@@ -100,7 +105,13 @@ class Server extends EventEmitter<Server.Events> {
100105
response = await this.routes.handle(apiRequest);
101106
}
102107
catch (e) {
103-
if (e instanceof RouteRegistry.NoRouteError)
108+
if (e instanceof ThrowableResponse) {
109+
response = e.getResponse();
110+
const cause = e.getError();
111+
if (cause !== null)
112+
this.emit("error", cause);
113+
}
114+
else if (e instanceof RouteRegistry.NoRouteError)
104115
response = this.errors._get(ServerErrorRegistry.ErrorCodes.NO_ROUTE, apiRequest);
105116
else {
106117
this.emit("error", e as any);

src/response/ThrowableResponse.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import {Response} from "./Response.js";
2+
3+
/**
4+
* An (error) response that is thrown. Will be caught by the server and sent to the client.
5+
*/
6+
export class ThrowableResponse<T extends Response> extends Error {
7+
public override name = ThrowableResponse.name;
8+
9+
/**
10+
* The response to send to the client.
11+
*/
12+
protected readonly response: T;
13+
14+
/**
15+
* An optional error to emit on the server’s error event.
16+
*/
17+
protected readonly error: Error | null;
18+
19+
/**
20+
* Create a new throwable response.
21+
* @param response The response to send to the client.
22+
* @param [error] An optional error to emit on the server’s error event.
23+
*/
24+
public constructor(response: T, error?: Error) {
25+
super();
26+
this.response = response;
27+
this.error = error ?? null;
28+
}
29+
30+
public getResponse(): T {
31+
return this.response;
32+
}
33+
34+
public getError(): Error | null {
35+
return this.error;
36+
}
37+
}

src/response/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ export * from "./EmptyResponse.js";
44
export * from "./JsonResponse.js";
55
export * from "./Response.js";
66
export * from "./TextResponse.js";
7+
export * from "./ThrowableResponse.js";

0 commit comments

Comments
 (0)