Skip to content

Commit 50195d2

Browse files
committed
Define some custom error classes
1 parent d305432 commit 50195d2

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

src/util/error.ts

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
const statusCodes = {
2+
ACCEPTED: 202,
3+
BAD_GATEWAY: 502,
4+
BAD_REQUEST: 400,
5+
CONFLICT: 409,
6+
CONTINUE: 100,
7+
CREATED: 201,
8+
EXPECTATION_FAILED: 417,
9+
FAILED_DEPENDENCY: 424,
10+
FORBIDDEN: 403,
11+
GATEWAY_TIMEOUT: 504,
12+
GONE: 410,
13+
HTTP_VERSION_NOT_SUPPORTED: 505,
14+
IM_A_TEAPOT: 418,
15+
INSUFFICIENT_SPACE_ON_RESOURCE: 419,
16+
INSUFFICIENT_STORAGE: 507,
17+
INTERNAL_SERVER_ERROR: 500,
18+
LENGTH_REQUIRED: 411,
19+
LOCKED: 423,
20+
METHOD_FAILURE: 420,
21+
METHOD_NOT_ALLOWED: 405,
22+
MOVED_PERMANENTLY: 301,
23+
MOVED_TEMPORARILY: 302,
24+
MULTI_STATUS: 207,
25+
MULTIPLE_CHOICES: 300,
26+
NETWORK_AUTHENTICATION_REQUIRED: 511,
27+
NO_CONTENT: 204,
28+
NON_AUTHORITATIVE_INFORMATION: 203,
29+
NOT_ACCEPTABLE: 406,
30+
NOT_FOUND: 404,
31+
NOT_IMPLEMENTED: 501,
32+
NOT_MODIFIED: 304,
33+
OK: 200,
34+
PARTIAL_CONTENT: 206,
35+
PAYMENT_REQUIRED: 402,
36+
PERMANENT_REDIRECT: 308,
37+
PRECONDITION_FAILED: 412,
38+
PRECONDITION_REQUIRED: 428,
39+
PROCESSING: 102,
40+
PROXY_AUTHENTICATION_REQUIRED: 407,
41+
REQUEST_HEADER_FIELDS_TOO_LARGE: 431,
42+
REQUEST_TIMEOUT: 408,
43+
REQUEST_TOO_LONG: 413,
44+
REQUEST_URI_TOO_LONG: 414,
45+
REQUESTED_RANGE_NOT_SATISFIABLE: 416,
46+
RESET_CONTENT: 205,
47+
SEE_OTHER: 303,
48+
SERVICE_UNAVAILABLE: 503,
49+
SWITCHING_PROTOCOLS: 101,
50+
TEMPORARY_REDIRECT: 307,
51+
TOO_MANY_REQUESTS: 429,
52+
UNAUTHORIZED: 401,
53+
UNAVAILABLE_FOR_LEGAL_REASONS: 451,
54+
UNPROCESSABLE_ENTITY: 422,
55+
UNSUPPORTED_MEDIA_TYPE: 415,
56+
USE_PROXY: 305,
57+
} as const;
58+
59+
type StatusCode = typeof statusCodes[keyof typeof statusCodes];
60+
61+
export class ExtendableError extends Error {
62+
constructor(message: string) {
63+
super(message);
64+
65+
/*
66+
* Due to a known issue (https://github.com/microsoft/TypeScript/issues/13965)
67+
* we need to set prototype manually, in order to get `instanceof` to work
68+
* for classes that extend `Error`
69+
*/
70+
Object.setPrototypeOf(this, ExtendableError.prototype);
71+
72+
this.name = this.constructor.name;
73+
74+
if (typeof Error.captureStackTrace === 'function') {
75+
Error.captureStackTrace(this, this.constructor);
76+
} else {
77+
this.stack = new Error(message).stack;
78+
}
79+
}
80+
}
81+
82+
type ErrorBody = {
83+
status: string;
84+
code: string;
85+
message: string;
86+
};
87+
88+
export class ForbiddenError extends ExtendableError {
89+
private readonly _originalError?: Error;
90+
private readonly namespace: string;
91+
private readonly body: ErrorBody;
92+
private readonly statusCode: StatusCode;
93+
94+
constructor(message: string, namespace?: string, originalError?: Error) {
95+
super(message);
96+
97+
/*
98+
* Due to a known issue (https://github.com/microsoft/TypeScript/issues/13965)
99+
* we need to set prototype manually, in order to get `instanceof` to work
100+
* for classes that extend `Error`
101+
*/
102+
Object.setPrototypeOf(this, ForbiddenError.prototype);
103+
104+
this.namespace = namespace + ':forbidden';
105+
this.name = 'ForbiddenError';
106+
this.statusCode = 403;
107+
108+
if (originalError) {
109+
this._originalError = originalError;
110+
}
111+
112+
this.body = { status: 'error', code: this.name, message };
113+
}
114+
}

0 commit comments

Comments
 (0)