Skip to content

Commit 51c9af7

Browse files
authored
Create errors.ts
1 parent 8d62f1a commit 51c9af7

File tree

1 file changed

+274
-0
lines changed

1 file changed

+274
-0
lines changed

src/middleware/errors.ts

+274
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
import { NextFunction, Request, Response } from "express";
2+
3+
/**
4+
* Philosophically don't look to adopt the perfect response shape,
5+
* instead look to adopt the one you like and then adapt it to your needs.
6+
* Errors, and adding RESTful information is a good ideal.
7+
* statusCode, error message, and stack trace or error payloads are enough for most cases.
8+
*/
9+
class HttpException extends Error {
10+
public readonly statusCode: number;
11+
public message: string;
12+
public name: string;
13+
public readonly data?: string;
14+
15+
/**
16+
* A generic Exception class for HTTP responses
17+
* @param statusCode {number} - HTTP status code
18+
* @param message {string} - Error message
19+
* @param name {string} - Error data
20+
* @param data {string} - Optional error payload
21+
*/
22+
constructor(status: number, message: string, name: string, data?: string) {
23+
super(message);
24+
this.statusCode = status;
25+
this.message = message;
26+
this.name = name;
27+
if (typeof data !== "undefined") {
28+
this.data = data;
29+
}
30+
}
31+
32+
/**
33+
*
34+
* @param message {string} - additional messages to be added to the error message
35+
*/
36+
appendMessage(message: string) {
37+
this.message += ` ${message}`;
38+
}
39+
}
40+
41+
const exceptions = [
42+
new HttpException(
43+
400,
44+
"The request syntax is malformed or invalid",
45+
"BadRequest"
46+
),
47+
new HttpException(
48+
401,
49+
"You are not authorized, the client must authenticate itself to get the requested response.",
50+
"Unauthorized"
51+
),
52+
new HttpException(402, "Payme", "PaymentRequired"),
53+
new HttpException(
54+
403,
55+
"You are not authorized, we know which user you are, but the item you requested is not allowed to be given to you",
56+
"Forbidden"
57+
),
58+
new HttpException(
59+
404,
60+
"The item you are looking for is not found",
61+
"NotFound"
62+
),
63+
new HttpException(
64+
405,
65+
"The method you are using is not allowed",
66+
"MethodNotAllowed"
67+
),
68+
new HttpException(
69+
406,
70+
"The requested resource is not available in the format you requested",
71+
"NotAcceptable"
72+
),
73+
new HttpException(407, "Proxy Authentication Required", "ProxyAuthRequired"),
74+
new HttpException(
75+
408,
76+
"The server timed out waiting for the request",
77+
"RequestTimeout"
78+
),
79+
new HttpException(
80+
409,
81+
"The request could not be processed because of conflict in the request",
82+
"Conflict"
83+
),
84+
new HttpException(
85+
410,
86+
"The requested resource is no longer available",
87+
"Gone"
88+
),
89+
new HttpException(
90+
411,
91+
"The request did not specify the length of its content, which is required by the requested resource",
92+
"LengthRequired"
93+
),
94+
new HttpException(
95+
412,
96+
"The server does not meet one of the preconditions that the requester put on the request",
97+
"PreconditionFailed"
98+
),
99+
new HttpException(
100+
413,
101+
"The request is larger than the server is willing or able to process",
102+
"RequestEntityTooLarge"
103+
),
104+
new HttpException(
105+
414,
106+
"The URI provided was too long for the server to process",
107+
"RequestURITooLong"
108+
),
109+
new HttpException(
110+
415,
111+
"The request entity has a media type which the server or resource does not support",
112+
"UnsupportedMediaType"
113+
),
114+
new HttpException(
115+
416,
116+
"The client has asked for a portion of the file, but the server cannot supply that portion",
117+
"RequestRangeNotSatisfiable"
118+
),
119+
new HttpException(
120+
417,
121+
"The server cannot meet the requirements of the Expect request-header field",
122+
"ExpectationFailed"
123+
),
124+
new HttpException(
125+
418,
126+
"The request was directed at a server that is not able to produce a response",
127+
"ImATeapot"
128+
),
129+
new HttpException(
130+
421,
131+
"The request was directed at a server that is not able to produce a response",
132+
"ImATeapot"
133+
),
134+
new HttpException(
135+
422,
136+
"The request was well-formed but was unable to be followed due to semantic errors",
137+
"UnprocessableEntity"
138+
),
139+
new HttpException(
140+
423,
141+
"The resource that is being accessed is locked",
142+
"Locked"
143+
),
144+
new HttpException(
145+
424,
146+
"The request failed due to failure of a previous request",
147+
"FailedDependency"
148+
),
149+
new HttpException(
150+
426,
151+
"The client should switch to a different protocol",
152+
"UpgradeRequired"
153+
),
154+
new HttpException(
155+
428,
156+
"The origin server requires the request to be conditional",
157+
"PreconditionRequired"
158+
),
159+
new HttpException(
160+
429,
161+
"The user has sent too many requests in a given amount of time. Intended for use with rate limiting schemes",
162+
"TooManyRequests"
163+
),
164+
new HttpException(
165+
431,
166+
"The server is unwilling to process the request because its header fields are too large",
167+
"RequestHeaderFieldsTooLarge"
168+
),
169+
new HttpException(
170+
451,
171+
"The server is denying access to the resource as a consequence of a legal demand",
172+
"UnavailableForLegalReasons"
173+
),
174+
new HttpException(
175+
500,
176+
"The server has encountered a situation it doesn't know how to handle",
177+
"InternalServerError"
178+
),
179+
new HttpException(
180+
501,
181+
"The request method is not supported by the server and cannot be handled",
182+
"NotImplemented"
183+
),
184+
new HttpException(
185+
502,
186+
"The server received an invalid response from a server it consulted when acting as a proxy or gateway",
187+
"BadGateway"
188+
),
189+
new HttpException(
190+
503,
191+
"The server is currently unavailable (because it is overloaded or down for maintenance)",
192+
"ServiceUnavailable"
193+
),
194+
new HttpException(
195+
504,
196+
"The server was acting as a gateway or proxy and did not receive a timely response from the upstream server",
197+
"GatewayTimeout"
198+
),
199+
new HttpException(
200+
505,
201+
"The server does not support the HTTP protocol version used in the request",
202+
"HTTPVersionNotSupported"
203+
),
204+
new HttpException(
205+
506,
206+
"Transparent content negotiation for the request results in a circular reference",
207+
"VariantAlsoNegotiates"
208+
),
209+
new HttpException(
210+
507,
211+
"The server is unable to store the representation needed to complete the request",
212+
"InsufficientStorage"
213+
),
214+
new HttpException(
215+
508,
216+
"The server detected an infinite loop while processing the request",
217+
"LoopDetected"
218+
),
219+
new HttpException(
220+
510,
221+
"Further extensions to the request are required for the server to fulfill it",
222+
"NotExtended"
223+
),
224+
new HttpException(
225+
511,
226+
"The client needs to authenticate to gain network access",
227+
"NetworkAuthenticationRequired"
228+
),
229+
];
230+
231+
/**
232+
*
233+
* @param statusCode {number} - the status code of the error
234+
* @returns {HttpException} - the exception
235+
*/
236+
function getExceptionByStatusCode(statusCode: number): HttpException {
237+
const exception = exceptions.find((e) => e.statusCode === statusCode);
238+
if (exception) {
239+
return exception;
240+
}
241+
return new HttpException(
242+
statusCode,
243+
`Unknown status code ${statusCode}`,
244+
"Unknown"
245+
);
246+
}
247+
248+
const code = getExceptionByStatusCode;
249+
250+
/**
251+
*
252+
* @param {Request} request - Express request object
253+
* @param {Response} response - Express response object
254+
* @param {NextFunction} next - Express next function
255+
*/
256+
function errorMiddleware(
257+
error: Error | HttpException,
258+
request: Request,
259+
response: Response,
260+
next: NextFunction
261+
) {
262+
if (response.headersSent) {
263+
return next(error);
264+
}
265+
if (error instanceof HttpException) {
266+
response.status(error.statusCode);
267+
response.send(error);
268+
} else {
269+
response.status(500);
270+
response.send(code(500));
271+
}
272+
}
273+
274+
export { errorMiddleware, exceptions, HttpException, code };

0 commit comments

Comments
 (0)