@marianmeres/http-utils 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +130 -99
- package/API.md +292 -197
- package/README.md +105 -49
- package/dist/api.d.ts +42 -0
- package/dist/api.js +77 -4
- package/dist/error.d.ts +28 -1
- package/dist/error.js +106 -64
- package/dist/mod.d.ts +2 -2
- package/dist/mod.js +2 -2
- package/dist/status.js +77 -61
- package/package.json +1 -1
package/dist/error.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* HTTP error classes and utilities for type-safe error handling.
|
|
5
5
|
* Provides specific error classes for well-known HTTP status codes.
|
|
6
6
|
*/
|
|
7
|
-
import { HTTP_STATUS } from
|
|
7
|
+
import { HTTP_STATUS } from "./status.js";
|
|
8
8
|
/**
|
|
9
9
|
* Base HTTP error class. Extends Error with HTTP-specific properties.
|
|
10
10
|
* All specific error classes (NotFound, BadRequest, etc.) extend this class.
|
|
@@ -23,7 +23,7 @@ import { HTTP_STATUS } from './status.js';
|
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
25
|
class HttpError extends Error {
|
|
26
|
-
name =
|
|
26
|
+
name = "HttpError";
|
|
27
27
|
/** HTTP status code (e.g., 404, 500) */
|
|
28
28
|
status = HTTP_STATUS.ERROR_SERVER.INTERNAL_SERVER_ERROR.CODE;
|
|
29
29
|
/** HTTP status text (e.g., "Not Found", "Internal Server Error") */
|
|
@@ -34,105 +34,134 @@ class HttpError extends Error {
|
|
|
34
34
|
// Client error classes (4xx)
|
|
35
35
|
/** HTTP 400 Bad Request error. */
|
|
36
36
|
class BadRequest extends HttpError {
|
|
37
|
-
name =
|
|
37
|
+
name = "HttpBadRequestError";
|
|
38
38
|
status = HTTP_STATUS.ERROR_CLIENT.BAD_REQUEST.CODE;
|
|
39
39
|
statusText = HTTP_STATUS.ERROR_CLIENT.BAD_REQUEST.TEXT;
|
|
40
40
|
}
|
|
41
41
|
/** HTTP 401 Unauthorized error. */
|
|
42
42
|
class Unauthorized extends HttpError {
|
|
43
|
-
name =
|
|
43
|
+
name = "HttpUnauthorizedError";
|
|
44
44
|
status = HTTP_STATUS.ERROR_CLIENT.UNAUTHORIZED.CODE;
|
|
45
45
|
statusText = HTTP_STATUS.ERROR_CLIENT.UNAUTHORIZED.TEXT;
|
|
46
46
|
}
|
|
47
47
|
/** HTTP 403 Forbidden error. */
|
|
48
48
|
class Forbidden extends HttpError {
|
|
49
|
-
name =
|
|
49
|
+
name = "HttpForbiddenError";
|
|
50
50
|
status = HTTP_STATUS.ERROR_CLIENT.FORBIDDEN.CODE;
|
|
51
51
|
statusText = HTTP_STATUS.ERROR_CLIENT.FORBIDDEN.TEXT;
|
|
52
52
|
}
|
|
53
53
|
/** HTTP 404 Not Found error. */
|
|
54
54
|
class NotFound extends HttpError {
|
|
55
|
-
name =
|
|
55
|
+
name = "HttpNotFoundError";
|
|
56
56
|
status = HTTP_STATUS.ERROR_CLIENT.NOT_FOUND.CODE;
|
|
57
57
|
statusText = HTTP_STATUS.ERROR_CLIENT.NOT_FOUND.TEXT;
|
|
58
58
|
}
|
|
59
59
|
/** HTTP 405 Method Not Allowed error. */
|
|
60
60
|
class MethodNotAllowed extends HttpError {
|
|
61
|
-
name =
|
|
61
|
+
name = "HttpMethodNotAllowedError";
|
|
62
62
|
status = HTTP_STATUS.ERROR_CLIENT.METHOD_NOT_ALLOWED.CODE;
|
|
63
63
|
statusText = HTTP_STATUS.ERROR_CLIENT.METHOD_NOT_ALLOWED.TEXT;
|
|
64
64
|
}
|
|
65
65
|
/** HTTP 408 Request Timeout error. */
|
|
66
66
|
class RequestTimeout extends HttpError {
|
|
67
|
-
name =
|
|
67
|
+
name = "HttpRequestTimeoutError";
|
|
68
68
|
status = HTTP_STATUS.ERROR_CLIENT.REQUEST_TIMEOUT.CODE;
|
|
69
69
|
statusText = HTTP_STATUS.ERROR_CLIENT.REQUEST_TIMEOUT.TEXT;
|
|
70
70
|
}
|
|
71
71
|
/** HTTP 409 Conflict error. */
|
|
72
72
|
class Conflict extends HttpError {
|
|
73
|
-
name =
|
|
73
|
+
name = "HttpConflictError";
|
|
74
74
|
status = HTTP_STATUS.ERROR_CLIENT.CONFLICT.CODE;
|
|
75
75
|
statusText = HTTP_STATUS.ERROR_CLIENT.CONFLICT.TEXT;
|
|
76
76
|
}
|
|
77
77
|
/** HTTP 410 Gone error. */
|
|
78
78
|
class Gone extends HttpError {
|
|
79
|
-
name =
|
|
79
|
+
name = "HttpGoneError";
|
|
80
80
|
status = HTTP_STATUS.ERROR_CLIENT.GONE.CODE;
|
|
81
81
|
statusText = HTTP_STATUS.ERROR_CLIENT.GONE.TEXT;
|
|
82
82
|
}
|
|
83
83
|
/** HTTP 411 Length Required error. */
|
|
84
84
|
class LengthRequired extends HttpError {
|
|
85
|
-
name =
|
|
85
|
+
name = "HttpLengthRequiredError";
|
|
86
86
|
status = HTTP_STATUS.ERROR_CLIENT.LENGTH_REQUIRED.CODE;
|
|
87
87
|
statusText = HTTP_STATUS.ERROR_CLIENT.LENGTH_REQUIRED.TEXT;
|
|
88
88
|
}
|
|
89
89
|
/** HTTP 422 Unprocessable Content error. */
|
|
90
90
|
class UnprocessableContent extends HttpError {
|
|
91
|
-
name =
|
|
91
|
+
name = "HttpUnprocessableContentError";
|
|
92
92
|
status = HTTP_STATUS.ERROR_CLIENT.UNPROCESSABLE_CONTENT.CODE;
|
|
93
93
|
statusText = HTTP_STATUS.ERROR_CLIENT.UNPROCESSABLE_CONTENT.TEXT;
|
|
94
94
|
}
|
|
95
95
|
/** HTTP 429 Too Many Requests error. */
|
|
96
96
|
class TooManyRequests extends HttpError {
|
|
97
|
-
name =
|
|
97
|
+
name = "HttpTooManyRequestsError";
|
|
98
98
|
status = HTTP_STATUS.ERROR_CLIENT.TOO_MANY_REQUESTS.CODE;
|
|
99
99
|
statusText = HTTP_STATUS.ERROR_CLIENT.TOO_MANY_REQUESTS.TEXT;
|
|
100
100
|
}
|
|
101
101
|
/** HTTP 418 I'm a Teapot error. */
|
|
102
102
|
class ImATeapot extends HttpError {
|
|
103
|
-
name =
|
|
103
|
+
name = "HttpImATeapotError";
|
|
104
104
|
status = HTTP_STATUS.ERROR_CLIENT.IM_A_TEAPOT.CODE;
|
|
105
105
|
statusText = HTTP_STATUS.ERROR_CLIENT.IM_A_TEAPOT.TEXT;
|
|
106
106
|
}
|
|
107
107
|
// Server error classes (5xx)
|
|
108
108
|
/** HTTP 500 Internal Server Error. */
|
|
109
109
|
class InternalServerError extends HttpError {
|
|
110
|
-
name =
|
|
110
|
+
name = "HttpInternalServerError";
|
|
111
111
|
}
|
|
112
112
|
/** HTTP 501 Not Implemented error. */
|
|
113
113
|
class NotImplemented extends HttpError {
|
|
114
|
-
name =
|
|
114
|
+
name = "HttpNotImplementedError";
|
|
115
115
|
status = HTTP_STATUS.ERROR_SERVER.NOT_IMPLEMENTED.CODE;
|
|
116
116
|
statusText = HTTP_STATUS.ERROR_SERVER.NOT_IMPLEMENTED.TEXT;
|
|
117
117
|
}
|
|
118
118
|
/** HTTP 502 Bad Gateway error. */
|
|
119
119
|
class BadGateway extends HttpError {
|
|
120
|
-
name =
|
|
120
|
+
name = "HttpBadGatewayError";
|
|
121
121
|
status = HTTP_STATUS.ERROR_SERVER.BAD_GATEWAY.CODE;
|
|
122
122
|
statusText = HTTP_STATUS.ERROR_SERVER.BAD_GATEWAY.TEXT;
|
|
123
123
|
}
|
|
124
124
|
/** HTTP 503 Service Unavailable error. */
|
|
125
125
|
class ServiceUnavailable extends HttpError {
|
|
126
|
-
name =
|
|
126
|
+
name = "HttpServiceUnavailableError";
|
|
127
127
|
status = HTTP_STATUS.ERROR_SERVER.SERVICE_UNAVAILABLE.CODE;
|
|
128
128
|
statusText = HTTP_STATUS.ERROR_SERVER.SERVICE_UNAVAILABLE.TEXT;
|
|
129
129
|
}
|
|
130
|
+
// Transport-level error (no HTTP response was received)
|
|
131
|
+
/**
|
|
132
|
+
* Transport-level failure: DNS resolution failure, refused connection, connect
|
|
133
|
+
* timeout, unreachable host, etc. No HTTP response was received, so `status` is
|
|
134
|
+
* `0` (the de-facto web convention for network-level failures, mirroring
|
|
135
|
+
* `XMLHttpRequest.status`). Thrown by `fetchOrThrow` (and, by extension, by the
|
|
136
|
+
* `HttpApi` client) with the underlying transport error attached as `cause`, so
|
|
137
|
+
* the real reason (`ENOTFOUND`, `ECONNREFUSED`, ...) is never swallowed behind
|
|
138
|
+
* an opaque "fetch failed".
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```ts
|
|
142
|
+
* try {
|
|
143
|
+
* await api.get("/resource");
|
|
144
|
+
* } catch (error) {
|
|
145
|
+
* if (error instanceof HTTP_ERROR.NetworkError) {
|
|
146
|
+
* console.log(error.message); // e.g. "GET unreachable (https://...): ECONNREFUSED"
|
|
147
|
+
* console.log(error.cause); // the underlying transport error
|
|
148
|
+
* }
|
|
149
|
+
* }
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
class NetworkError extends HttpError {
|
|
153
|
+
name = "HttpNetworkError";
|
|
154
|
+
status = 0;
|
|
155
|
+
statusText = "Network Error";
|
|
156
|
+
}
|
|
130
157
|
// Export individual error classes for direct imports
|
|
131
|
-
export {
|
|
158
|
+
export { BadGateway,
|
|
132
159
|
// Client errors
|
|
133
|
-
BadRequest,
|
|
160
|
+
BadRequest, Conflict, Forbidden, Gone, HttpError, ImATeapot,
|
|
134
161
|
// Server errors
|
|
135
|
-
InternalServerError,
|
|
162
|
+
InternalServerError, LengthRequired, MethodNotAllowed,
|
|
163
|
+
// Transport error
|
|
164
|
+
NetworkError, NotFound, NotImplemented, RequestTimeout, ServiceUnavailable, TooManyRequests, Unauthorized, UnprocessableContent, };
|
|
136
165
|
/**
|
|
137
166
|
* Namespace containing all HTTP error classes for convenient access.
|
|
138
167
|
*
|
|
@@ -173,28 +202,30 @@ export const HTTP_ERROR = {
|
|
|
173
202
|
NotImplemented,
|
|
174
203
|
BadGateway,
|
|
175
204
|
ServiceUnavailable,
|
|
205
|
+
// transport
|
|
206
|
+
NetworkError,
|
|
176
207
|
};
|
|
177
208
|
const _wellKnownCtorMap = {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
209
|
+
"400": BadRequest,
|
|
210
|
+
"401": Unauthorized,
|
|
211
|
+
"403": Forbidden,
|
|
212
|
+
"404": NotFound,
|
|
213
|
+
"405": MethodNotAllowed,
|
|
214
|
+
"408": RequestTimeout,
|
|
215
|
+
"409": Conflict,
|
|
216
|
+
"410": Gone,
|
|
217
|
+
"411": LengthRequired,
|
|
218
|
+
"418": ImATeapot,
|
|
219
|
+
"422": UnprocessableContent,
|
|
220
|
+
"429": TooManyRequests,
|
|
190
221
|
//
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
222
|
+
"500": InternalServerError,
|
|
223
|
+
"501": NotImplemented,
|
|
224
|
+
"502": BadGateway,
|
|
225
|
+
"503": ServiceUnavailable,
|
|
195
226
|
};
|
|
196
227
|
const _maybeJsonParse = (v) => {
|
|
197
|
-
if (typeof v ===
|
|
228
|
+
if (typeof v === "string") {
|
|
198
229
|
try {
|
|
199
230
|
return JSON.parse(v);
|
|
200
231
|
}
|
|
@@ -233,7 +264,8 @@ export const createHttpError = (code, message, body, cause) => {
|
|
|
233
264
|
body = _maybeJsonParse(body);
|
|
234
265
|
cause = _maybeJsonParse(cause);
|
|
235
266
|
// try to find the well known one, otherwise fallback to generic
|
|
236
|
-
const ctor = _wellKnownCtorMap[`${code}`] ??
|
|
267
|
+
const ctor = _wellKnownCtorMap[`${code}`] ??
|
|
268
|
+
HttpError;
|
|
237
269
|
//
|
|
238
270
|
const found = HTTP_STATUS.findByCode(code);
|
|
239
271
|
const statusText = found?.TEXT ?? fallback.TEXT;
|
|
@@ -271,7 +303,7 @@ export const createHttpError = (code, message, body, cause) => {
|
|
|
271
303
|
*/
|
|
272
304
|
export const getErrorMessage = (e, stripErrorPrefix = true) => {
|
|
273
305
|
if (!e)
|
|
274
|
-
return
|
|
306
|
+
return "";
|
|
275
307
|
// Errors may bubble from various sources which are not always under control.
|
|
276
308
|
// We try our best to extract a meaningful message using common conventions.
|
|
277
309
|
const err = e;
|
|
@@ -282,36 +314,46 @@ export const getErrorMessage = (e, stripErrorPrefix = true) => {
|
|
|
282
314
|
// e.cause is the standard prop for error details, so should be considered as
|
|
283
315
|
// the most authoritative (if available)
|
|
284
316
|
// "code" and "message" are my own conventions
|
|
285
|
-
(typeof cause ===
|
|
286
|
-
(typeof cause ===
|
|
287
|
-
(typeof cause ===
|
|
317
|
+
(typeof cause === "object" ? cause?.message : null) ||
|
|
318
|
+
(typeof cause === "object" ? cause?.code : null) ||
|
|
319
|
+
(typeof cause === "string" ? cause : null) ||
|
|
288
320
|
// additional well-known cause shapes (RFC 7807, OAuth 2, nested OAuth)
|
|
289
|
-
(typeof cause ===
|
|
290
|
-
(typeof cause ===
|
|
291
|
-
(typeof cause ===
|
|
292
|
-
|
|
321
|
+
(typeof cause === "object" ? cause?.detail : null) ||
|
|
322
|
+
(typeof cause === "object" ? cause?.error_description : null) ||
|
|
323
|
+
(typeof cause === "object"
|
|
324
|
+
? cause?.error?.error_description
|
|
325
|
+
: null) ||
|
|
326
|
+
(typeof cause === "object"
|
|
327
|
+
? cause?.error?.detail
|
|
328
|
+
: null) ||
|
|
293
329
|
// non-standard "body" is this package's HttpError prop
|
|
294
|
-
(typeof body ===
|
|
295
|
-
|
|
330
|
+
(typeof body === "object"
|
|
331
|
+
? body?.error?.message
|
|
332
|
+
: null) ||
|
|
333
|
+
(typeof body === "object" ? body?.message : null) ||
|
|
296
334
|
// nested under body.error (OAuth-style nested + RFC 7807 nested)
|
|
297
|
-
(typeof body ===
|
|
298
|
-
|
|
335
|
+
(typeof body === "object"
|
|
336
|
+
? body?.error?.error_description
|
|
337
|
+
: null) ||
|
|
338
|
+
(typeof body === "object"
|
|
339
|
+
? body?.error?.detail
|
|
340
|
+
: null) ||
|
|
299
341
|
// RFC 7807 (Problem Details) / DRF / FastAPI
|
|
300
|
-
(typeof body ===
|
|
301
|
-
(typeof body ===
|
|
342
|
+
(typeof body === "object" ? body?.detail : null) ||
|
|
343
|
+
(typeof body === "object" ? body?.title : null) ||
|
|
302
344
|
// OAuth 2 (RFC 6749) — must precede `body.error` so error_description wins over the error code
|
|
303
|
-
(typeof body ===
|
|
345
|
+
(typeof body === "object" ? body?.error_description : null) ||
|
|
304
346
|
// JSON:API / generic errors[] — first entry's detail/title/message, else string
|
|
305
|
-
(typeof body ===
|
|
306
|
-
? (typeof body.errors[0] ===
|
|
347
|
+
(typeof body === "object" && Array.isArray(body?.errors)
|
|
348
|
+
? (typeof body.errors[0] === "string"
|
|
307
349
|
? body.errors[0]
|
|
308
|
-
: (body.errors[0]?.detail
|
|
309
|
-
|
|
310
|
-
|
|
350
|
+
: (body.errors[0]?.detail ||
|
|
351
|
+
body.errors[0]?.title ||
|
|
352
|
+
body.errors[0]?.message))
|
|
311
353
|
: null) ||
|
|
312
354
|
// fallback: body.error as plain string (e.g. OAuth error code without description)
|
|
313
|
-
(typeof body ===
|
|
314
|
-
(typeof body ===
|
|
355
|
+
(typeof body === "object" ? body?.error : null) ||
|
|
356
|
+
(typeof body === "string" ? body : null) ||
|
|
315
357
|
// the common message from Error ctor (e.g. "Foo" if new TypeError("Foo"))
|
|
316
358
|
err?.message ||
|
|
317
359
|
// Node.js error code fallback (e.g. "ECONNREFUSED") when message is empty
|
|
@@ -319,11 +361,11 @@ export const getErrorMessage = (e, stripErrorPrefix = true) => {
|
|
|
319
361
|
// the Error class name (e.g. TypeError)
|
|
320
362
|
err?.name ||
|
|
321
363
|
// this should handle (almost) everything else (mainly if e is not an Error instance)
|
|
322
|
-
(typeof err?.toString ===
|
|
364
|
+
(typeof err?.toString === "function" ? err.toString() : null) ||
|
|
323
365
|
// very last fallback if `toString()` was not available (or returned empty)
|
|
324
|
-
|
|
366
|
+
"Unknown Error");
|
|
325
367
|
if (stripErrorPrefix) {
|
|
326
|
-
msg = msg.replace(/^[^:]*Error: /i,
|
|
368
|
+
msg = msg.replace(/^[^:]*Error: /i, "");
|
|
327
369
|
}
|
|
328
370
|
return msg;
|
|
329
371
|
};
|
package/dist/mod.d.ts
CHANGED
|
@@ -21,6 +21,6 @@
|
|
|
21
21
|
* }
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
|
-
export {
|
|
25
|
-
export {
|
|
24
|
+
export { createHttpApi, type DataOptions, type ErrorMessageExtractor, fetchOrThrow, type FetchParams, type GetOptions, HttpApi, opts, type QueryValue, type RequestData, type RequestInterceptor, type ResponseHeaders, type ResponseInterceptor, } from "./api.js";
|
|
25
|
+
export { createHttpError, getErrorMessage, HTTP_ERROR } from "./error.js";
|
|
26
26
|
export { HTTP_STATUS } from "./status.js";
|
package/dist/mod.js
CHANGED
|
@@ -21,6 +21,6 @@
|
|
|
21
21
|
* }
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
|
-
export {
|
|
25
|
-
export {
|
|
24
|
+
export { createHttpApi, fetchOrThrow, HttpApi, opts, } from "./api.js";
|
|
25
|
+
export { createHttpError, getErrorMessage, HTTP_ERROR } from "./error.js";
|
|
26
26
|
export { HTTP_STATUS } from "./status.js";
|
package/dist/status.js
CHANGED
|
@@ -35,80 +35,92 @@ export class HTTP_STATUS {
|
|
|
35
35
|
// Full database of HTTP status codes
|
|
36
36
|
// 1xx
|
|
37
37
|
static INFO = {
|
|
38
|
-
CONTINUE: { CODE: 100, TEXT:
|
|
39
|
-
SWITCHING_PROTOCOLS: { CODE: 101, TEXT:
|
|
40
|
-
PROCESSING: { CODE: 102, TEXT:
|
|
41
|
-
EARLY_HINTS: { CODE: 103, TEXT:
|
|
38
|
+
CONTINUE: { CODE: 100, TEXT: "Continue" },
|
|
39
|
+
SWITCHING_PROTOCOLS: { CODE: 101, TEXT: "Switching Protocols" },
|
|
40
|
+
PROCESSING: { CODE: 102, TEXT: "Processing" },
|
|
41
|
+
EARLY_HINTS: { CODE: 103, TEXT: "Early Hints" },
|
|
42
42
|
};
|
|
43
43
|
// 2xx
|
|
44
44
|
static SUCCESS = {
|
|
45
|
-
OK: { CODE: 200, TEXT:
|
|
46
|
-
CREATED: { CODE: 201, TEXT:
|
|
47
|
-
ACCEPTED: { CODE: 202, TEXT:
|
|
48
|
-
NON_AUTHORITATIVE_INFO: { CODE: 203, TEXT:
|
|
49
|
-
NO_CONTENT: { CODE: 204, TEXT:
|
|
50
|
-
RESET_CONTENT: { CODE: 205, TEXT:
|
|
51
|
-
PARTIAL_CONTENT: { CODE: 206, TEXT:
|
|
52
|
-
MULTI_STATUS: { CODE: 207, TEXT:
|
|
53
|
-
ALREADY_REPORTED: { CODE: 208, TEXT:
|
|
54
|
-
IM_USED: { CODE: 226, TEXT:
|
|
45
|
+
OK: { CODE: 200, TEXT: "OK" },
|
|
46
|
+
CREATED: { CODE: 201, TEXT: "Created" },
|
|
47
|
+
ACCEPTED: { CODE: 202, TEXT: "Accepted" },
|
|
48
|
+
NON_AUTHORITATIVE_INFO: { CODE: 203, TEXT: "Non-Authoritative Information" },
|
|
49
|
+
NO_CONTENT: { CODE: 204, TEXT: "No Content" },
|
|
50
|
+
RESET_CONTENT: { CODE: 205, TEXT: "Reset Content" },
|
|
51
|
+
PARTIAL_CONTENT: { CODE: 206, TEXT: "Partial Content" },
|
|
52
|
+
MULTI_STATUS: { CODE: 207, TEXT: "Multi-Status" },
|
|
53
|
+
ALREADY_REPORTED: { CODE: 208, TEXT: "Already Reported" },
|
|
54
|
+
IM_USED: { CODE: 226, TEXT: "IM Used" }, // ?
|
|
55
55
|
};
|
|
56
56
|
// 3xx
|
|
57
57
|
static REDIRECT = {
|
|
58
|
-
MULTIPLE_CHOICES: { CODE: 300, TEXT:
|
|
59
|
-
MOVED_PERMANENTLY: { CODE: 301, TEXT:
|
|
60
|
-
FOUND: { CODE: 302, TEXT:
|
|
61
|
-
SEE_OTHER: { CODE: 303, TEXT:
|
|
62
|
-
NOT_MODIFIED: { CODE: 304, TEXT:
|
|
63
|
-
TEMPORARY_REDIRECT: { CODE: 307, TEXT:
|
|
64
|
-
PERMANENT_REDIRECT: { CODE: 308, TEXT:
|
|
58
|
+
MULTIPLE_CHOICES: { CODE: 300, TEXT: "Multiple Choices" },
|
|
59
|
+
MOVED_PERMANENTLY: { CODE: 301, TEXT: "Moved Permanently" },
|
|
60
|
+
FOUND: { CODE: 302, TEXT: "Found" },
|
|
61
|
+
SEE_OTHER: { CODE: 303, TEXT: "See Other" },
|
|
62
|
+
NOT_MODIFIED: { CODE: 304, TEXT: "Not Modified" },
|
|
63
|
+
TEMPORARY_REDIRECT: { CODE: 307, TEXT: "Temporary Redirect" },
|
|
64
|
+
PERMANENT_REDIRECT: { CODE: 308, TEXT: "Permanent Redirect" },
|
|
65
65
|
};
|
|
66
66
|
// 4xx
|
|
67
67
|
static ERROR_CLIENT = {
|
|
68
|
-
BAD_REQUEST: { CODE: 400, TEXT:
|
|
69
|
-
UNAUTHORIZED: { CODE: 401, TEXT:
|
|
70
|
-
PAYMENT_REQUIRED_EXPERIMENTAL: {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
68
|
+
BAD_REQUEST: { CODE: 400, TEXT: "Bad Request" },
|
|
69
|
+
UNAUTHORIZED: { CODE: 401, TEXT: "Unauthorized" },
|
|
70
|
+
PAYMENT_REQUIRED_EXPERIMENTAL: {
|
|
71
|
+
CODE: 402,
|
|
72
|
+
TEXT: "Payment Required Experimental",
|
|
73
|
+
},
|
|
74
|
+
FORBIDDEN: { CODE: 403, TEXT: "Forbidden" },
|
|
75
|
+
NOT_FOUND: { CODE: 404, TEXT: "Not Found" },
|
|
76
|
+
METHOD_NOT_ALLOWED: { CODE: 405, TEXT: "Method Not Allowed" },
|
|
77
|
+
NOT_ACCEPTABLE: { CODE: 406, TEXT: "Not Acceptable" },
|
|
78
|
+
PROXY_AUTHENTICATION_REQUIRED: {
|
|
79
|
+
CODE: 407,
|
|
80
|
+
TEXT: "Proxy Authentication Required",
|
|
81
|
+
},
|
|
82
|
+
REQUEST_TIMEOUT: { CODE: 408, TEXT: "Request Timeout" },
|
|
83
|
+
CONFLICT: { CODE: 409, TEXT: "Conflict" },
|
|
84
|
+
GONE: { CODE: 410, TEXT: "Gone" },
|
|
85
|
+
LENGTH_REQUIRED: { CODE: 411, TEXT: "Length Required" },
|
|
86
|
+
PRECONDITION_FAILED: { CODE: 412, TEXT: "Precondition Failed" },
|
|
87
|
+
PAYLOAD_TOO_LARGE: { CODE: 413, TEXT: "Payload Too Large" },
|
|
88
|
+
URI_TOO_LONG: { CODE: 414, TEXT: "URI Too Long" },
|
|
89
|
+
UNSUPPORTED_MEDIA_TYPE: { CODE: 415, TEXT: "Unsupported Media Type" },
|
|
90
|
+
RANGE_NOT_SATISFIABLE: { CODE: 416, TEXT: "Range Not Satisfiable" },
|
|
91
|
+
EXPECTATION_FAILED: { CODE: 417, TEXT: "Expectation Failed" },
|
|
86
92
|
IM_A_TEAPOT: { CODE: 418, TEXT: "I'm a teapot" },
|
|
87
|
-
MISDIRECTED_REQUEST: { CODE: 421, TEXT:
|
|
88
|
-
UNPROCESSABLE_CONTENT: { CODE: 422, TEXT:
|
|
89
|
-
LOCKED: { CODE: 423, TEXT:
|
|
90
|
-
FAILED_DEPENDENCY: { CODE: 424, TEXT:
|
|
91
|
-
TOO_EARLY_EXPERIMENTAL: { CODE: 425, TEXT:
|
|
92
|
-
UPGRADE_REQUIRED: { CODE: 426, TEXT:
|
|
93
|
-
PRECONDITION_REQUIRED: { CODE: 428, TEXT:
|
|
94
|
-
TOO_MANY_REQUESTS: { CODE: 429, TEXT:
|
|
95
|
-
REQUEST_HEADER_FIELDS_TOO_LARGE: {
|
|
96
|
-
|
|
93
|
+
MISDIRECTED_REQUEST: { CODE: 421, TEXT: "Misdirected Request" },
|
|
94
|
+
UNPROCESSABLE_CONTENT: { CODE: 422, TEXT: "Unprocessable Content" },
|
|
95
|
+
LOCKED: { CODE: 423, TEXT: "Locked" },
|
|
96
|
+
FAILED_DEPENDENCY: { CODE: 424, TEXT: "Failed Dependency" },
|
|
97
|
+
TOO_EARLY_EXPERIMENTAL: { CODE: 425, TEXT: "Too Early Experimental" },
|
|
98
|
+
UPGRADE_REQUIRED: { CODE: 426, TEXT: "Upgrade Required" },
|
|
99
|
+
PRECONDITION_REQUIRED: { CODE: 428, TEXT: "Precondition Required" },
|
|
100
|
+
TOO_MANY_REQUESTS: { CODE: 429, TEXT: "Too Many Requests" },
|
|
101
|
+
REQUEST_HEADER_FIELDS_TOO_LARGE: {
|
|
102
|
+
CODE: 431,
|
|
103
|
+
TEXT: "Request Header Fields Too Large",
|
|
104
|
+
},
|
|
105
|
+
UNAVAILABLE_FOR_LEGAL_REASONS: {
|
|
106
|
+
CODE: 451,
|
|
107
|
+
TEXT: "Unavailable For Legal Reasons",
|
|
108
|
+
},
|
|
97
109
|
};
|
|
98
110
|
// 5xx
|
|
99
111
|
// prettier-ignore
|
|
100
112
|
static ERROR_SERVER = {
|
|
101
|
-
INTERNAL_SERVER_ERROR: { CODE: 500, TEXT:
|
|
102
|
-
NOT_IMPLEMENTED: { CODE: 501, TEXT:
|
|
103
|
-
BAD_GATEWAY: { CODE: 502, TEXT:
|
|
104
|
-
SERVICE_UNAVAILABLE: { CODE: 503, TEXT:
|
|
105
|
-
GATEWAY_TIMEOUT: { CODE: 504, TEXT:
|
|
106
|
-
HTTP_VERSION_NOT_SUPPORTED: { CODE: 505, TEXT:
|
|
107
|
-
VARIANT_ALSO_NEGOTIATES: { CODE: 506, TEXT:
|
|
108
|
-
INSUFFICIENT_STORAGE: { CODE: 507, TEXT:
|
|
109
|
-
LOOP_DETECTED: { CODE: 508, TEXT:
|
|
110
|
-
NOT_EXTENDED: { CODE: 510, TEXT:
|
|
111
|
-
NETWORK_AUTH_REQUIRED: { CODE: 511, TEXT:
|
|
113
|
+
INTERNAL_SERVER_ERROR: { CODE: 500, TEXT: "Internal Server Error" },
|
|
114
|
+
NOT_IMPLEMENTED: { CODE: 501, TEXT: "Not Implemented" },
|
|
115
|
+
BAD_GATEWAY: { CODE: 502, TEXT: "Bad Gateway" },
|
|
116
|
+
SERVICE_UNAVAILABLE: { CODE: 503, TEXT: "Service Unavailable" },
|
|
117
|
+
GATEWAY_TIMEOUT: { CODE: 504, TEXT: "Gateway Timeout" },
|
|
118
|
+
HTTP_VERSION_NOT_SUPPORTED: { CODE: 505, TEXT: "HTTP Version Not Supported" },
|
|
119
|
+
VARIANT_ALSO_NEGOTIATES: { CODE: 506, TEXT: "Variant Also Negotiates" },
|
|
120
|
+
INSUFFICIENT_STORAGE: { CODE: 507, TEXT: "Insufficient Storage" },
|
|
121
|
+
LOOP_DETECTED: { CODE: 508, TEXT: "Loop Detected" },
|
|
122
|
+
NOT_EXTENDED: { CODE: 510, TEXT: "Not Extended" },
|
|
123
|
+
NETWORK_AUTH_REQUIRED: { CODE: 511, TEXT: "Network Authentication Required" },
|
|
112
124
|
};
|
|
113
125
|
// Convenience shortcuts: direct access to frequently used status codes
|
|
114
126
|
// 2xx
|
|
@@ -151,7 +163,11 @@ export class HTTP_STATUS {
|
|
|
151
163
|
*/
|
|
152
164
|
static findByCode(code) {
|
|
153
165
|
const keys = [
|
|
154
|
-
|
|
166
|
+
"INFO",
|
|
167
|
+
"SUCCESS",
|
|
168
|
+
"REDIRECT",
|
|
169
|
+
"ERROR_CLIENT",
|
|
170
|
+
"ERROR_SERVER",
|
|
155
171
|
];
|
|
156
172
|
for (const _TYPE of keys) {
|
|
157
173
|
const entries = Object.entries(HTTP_STATUS[_TYPE]);
|