@geekmidas/errors 0.1.0 → 1.0.1

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/src/index.ts CHANGED
@@ -14,115 +14,114 @@
14
14
  * ```
15
15
  */
16
16
  export class HttpError extends Error {
17
- /** The HTTP status code (e.g., 400, 404, 500) */
18
- public readonly statusCode: number;
19
- /** The standard HTTP status message (e.g., 'Bad Request', 'Not Found') */
20
- public readonly statusMessage: string;
21
- /** Type discriminator for runtime type checking */
22
- public readonly isHttpError = true;
23
- /** Additional error details for debugging or client information */
24
- public readonly details?: any;
25
- /** Application-specific error code for client-side handling */
26
- public readonly code?: string;
27
-
28
- /**
29
- * Creates a new HttpError instance.
30
- *
31
- * @param statusCode - The HTTP status code
32
- * @param message - Optional error message for the client
33
- * @param options - Optional configuration object
34
- * @param options.statusMessage - Override the default status message
35
- * @param options.details - Additional error details or context
36
- * @param options.code - Application-specific error code
37
- * @param options.cause - The underlying error that caused this error (ES2022)
38
- */
39
- constructor(
40
- statusCode: number,
41
- message?: string,
42
- options?: {
43
- statusMessage?: string;
44
- details?: any;
45
- code?: string;
46
- cause?: Error;
47
- },
48
- ) {
49
- super(message || options?.statusMessage || 'HTTP Error');
50
- this.name = this.constructor.name;
51
- this.statusCode = statusCode;
52
- this.statusMessage =
53
- options?.statusMessage || this.getDefaultStatusMessage(statusCode);
54
- this.details = options?.details;
55
- this.code = options?.code;
56
-
57
- // Set cause if provided (ES2022 feature)
58
- if (options?.cause) {
59
- this.cause = options.cause;
60
- }
61
- // @ts-ignore
62
- // Maintains proper stack trace for where our error was thrown
63
- Error.captureStackTrace(this, this.constructor);
64
- }
65
-
66
- /**
67
- * Gets the error response body as a JSON string.
68
- * Used for sending the error response to clients.
69
- *
70
- * @returns JSON string containing message, code, and error details
71
- */
72
- get body() {
73
- return JSON.stringify({
74
- message: this.message,
75
- code: this.code,
76
- error: this.details,
77
- });
78
- }
79
-
80
- /**
81
- * Gets the default HTTP status message for a given status code.
82
- *
83
- * @param statusCode - The HTTP status code
84
- * @returns The standard HTTP status message or 'Unknown Error' if not found
85
- * @private
86
- */
87
- private getDefaultStatusMessage(statusCode: number): string {
88
- const statusMessages: Record<number, string> = {
89
- 400: 'Bad Request',
90
- 401: 'Unauthorized',
91
- 403: 'Forbidden',
92
- 404: 'Not Found',
93
- 405: 'Method Not Allowed',
94
- 406: 'Not Acceptable',
95
- 408: 'Request Timeout',
96
- 409: 'Conflict',
97
- 410: 'Gone',
98
- 422: 'Unprocessable Entity',
99
- 429: 'Too Many Requests',
100
- 500: 'Internal Server Error',
101
- 501: 'Not Implemented',
102
- 502: 'Bad Gateway',
103
- 503: 'Service Unavailable',
104
- 504: 'Gateway Timeout',
105
- };
106
- return statusMessages[statusCode] || 'Unknown Error';
107
- }
108
-
109
- /**
110
- * Serializes the error to a JSON-compatible object.
111
- * Useful for logging and debugging purposes.
112
- *
113
- * @returns Object representation of the error including stack trace
114
- */
115
- toJSON() {
116
- return {
117
- name: this.name,
118
- message: this.message,
119
- statusCode: this.statusCode,
120
- statusMessage: this.statusMessage,
121
- code: this.code,
122
- details: this.details,
123
- stack: this.stack,
124
- };
125
- }
17
+ /** The HTTP status code (e.g., 400, 404, 500) */
18
+ public readonly statusCode: number;
19
+ /** The standard HTTP status message (e.g., 'Bad Request', 'Not Found') */
20
+ public readonly statusMessage: string;
21
+ /** Type discriminator for runtime type checking */
22
+ public readonly isHttpError = true;
23
+ /** Additional error details for debugging or client information */
24
+ public readonly details?: any;
25
+ /** Application-specific error code for client-side handling */
26
+ public readonly code?: string;
27
+
28
+ /**
29
+ * Creates a new HttpError instance.
30
+ *
31
+ * @param statusCode - The HTTP status code
32
+ * @param message - Optional error message for the client
33
+ * @param options - Optional configuration object
34
+ * @param options.statusMessage - Override the default status message
35
+ * @param options.details - Additional error details or context
36
+ * @param options.code - Application-specific error code
37
+ * @param options.cause - The underlying error that caused this error (ES2022)
38
+ */
39
+ constructor(
40
+ statusCode: number,
41
+ message?: string,
42
+ options?: {
43
+ statusMessage?: string;
44
+ details?: any;
45
+ code?: string;
46
+ cause?: Error;
47
+ },
48
+ ) {
49
+ super(message || options?.statusMessage || 'HTTP Error');
50
+ this.name = this.constructor.name;
51
+ this.statusCode = statusCode;
52
+ this.statusMessage =
53
+ options?.statusMessage || this.getDefaultStatusMessage(statusCode);
54
+ this.details = options?.details;
55
+ this.code = options?.code;
56
+
57
+ // Set cause if provided (ES2022 feature)
58
+ if (options?.cause) {
59
+ this.cause = options.cause;
60
+ }
61
+ // Maintains proper stack trace for where our error was thrown
62
+ Error.captureStackTrace(this, this.constructor);
63
+ }
64
+
65
+ /**
66
+ * Gets the error response body as a JSON string.
67
+ * Used for sending the error response to clients.
68
+ *
69
+ * @returns JSON string containing message, code, and error details
70
+ */
71
+ get body() {
72
+ return JSON.stringify({
73
+ message: this.message,
74
+ code: this.code,
75
+ error: this.details,
76
+ });
77
+ }
78
+
79
+ /**
80
+ * Gets the default HTTP status message for a given status code.
81
+ *
82
+ * @param statusCode - The HTTP status code
83
+ * @returns The standard HTTP status message or 'Unknown Error' if not found
84
+ * @private
85
+ */
86
+ private getDefaultStatusMessage(statusCode: number): string {
87
+ const statusMessages: Record<number, string> = {
88
+ 400: 'Bad Request',
89
+ 401: 'Unauthorized',
90
+ 403: 'Forbidden',
91
+ 404: 'Not Found',
92
+ 405: 'Method Not Allowed',
93
+ 406: 'Not Acceptable',
94
+ 408: 'Request Timeout',
95
+ 409: 'Conflict',
96
+ 410: 'Gone',
97
+ 422: 'Unprocessable Entity',
98
+ 429: 'Too Many Requests',
99
+ 500: 'Internal Server Error',
100
+ 501: 'Not Implemented',
101
+ 502: 'Bad Gateway',
102
+ 503: 'Service Unavailable',
103
+ 504: 'Gateway Timeout',
104
+ };
105
+ return statusMessages[statusCode] || 'Unknown Error';
106
+ }
107
+
108
+ /**
109
+ * Serializes the error to a JSON-compatible object.
110
+ * Useful for logging and debugging purposes.
111
+ *
112
+ * @returns Object representation of the error including stack trace
113
+ */
114
+ toJSON() {
115
+ return {
116
+ name: this.name,
117
+ message: this.message,
118
+ statusCode: this.statusCode,
119
+ statusMessage: this.statusMessage,
120
+ code: this.code,
121
+ details: this.details,
122
+ stack: this.stack,
123
+ };
124
+ }
126
125
  }
127
126
 
128
127
  // Client Error Classes (4xx)
@@ -139,9 +138,9 @@ export class HttpError extends Error {
139
138
  * ```
140
139
  */
141
140
  export class BadRequestError extends HttpError {
142
- constructor(message?: string, details?: any) {
143
- super(400, message, { details });
144
- }
141
+ constructor(message?: string, details?: any) {
142
+ super(400, message, { details });
143
+ }
145
144
  }
146
145
 
147
146
  /**
@@ -156,9 +155,9 @@ export class BadRequestError extends HttpError {
156
155
  * ```
157
156
  */
158
157
  export class UnauthorizedError extends HttpError {
159
- constructor(message?: string, details?: any) {
160
- super(401, message, { details });
161
- }
158
+ constructor(message?: string, details?: any) {
159
+ super(401, message, { details });
160
+ }
162
161
  }
163
162
 
164
163
  /**
@@ -173,9 +172,9 @@ export class UnauthorizedError extends HttpError {
173
172
  * ```
174
173
  */
175
174
  export class ForbiddenError extends HttpError {
176
- constructor(message?: string, details?: any) {
177
- super(403, message, { details });
178
- }
175
+ constructor(message?: string, details?: any) {
176
+ super(403, message, { details });
177
+ }
179
178
  }
180
179
 
181
180
  /**
@@ -190,9 +189,9 @@ export class ForbiddenError extends HttpError {
190
189
  * ```
191
190
  */
192
191
  export class NotFoundError extends HttpError {
193
- constructor(message?: string, details?: any) {
194
- super(404, message, { details });
195
- }
192
+ constructor(message?: string, details?: any) {
193
+ super(404, message, { details });
194
+ }
196
195
  }
197
196
 
198
197
  /**
@@ -207,15 +206,15 @@ export class NotFoundError extends HttpError {
207
206
  * ```
208
207
  */
209
208
  export class MethodNotAllowedError extends HttpError {
210
- /**
211
- * @param message - Optional error message
212
- * @param allowedMethods - Array of allowed HTTP methods for this resource
213
- */
214
- constructor(message?: string, allowedMethods?: string[]) {
215
- super(405, message, {
216
- details: allowedMethods ? { allowedMethods } : undefined,
217
- });
218
- }
209
+ /**
210
+ * @param message - Optional error message
211
+ * @param allowedMethods - Array of allowed HTTP methods for this resource
212
+ */
213
+ constructor(message?: string, allowedMethods?: string[]) {
214
+ super(405, message, {
215
+ details: allowedMethods ? { allowedMethods } : undefined,
216
+ });
217
+ }
219
218
  }
220
219
 
221
220
  /**
@@ -230,9 +229,9 @@ export class MethodNotAllowedError extends HttpError {
230
229
  * ```
231
230
  */
232
231
  export class ConflictError extends HttpError {
233
- constructor(message?: string, details?: any) {
234
- super(409, message, { details });
235
- }
232
+ constructor(message?: string, details?: any) {
233
+ super(409, message, { details });
234
+ }
236
235
  }
237
236
 
238
237
  /**
@@ -250,15 +249,15 @@ export class ConflictError extends HttpError {
250
249
  * ```
251
250
  */
252
251
  export class UnprocessableEntityError extends HttpError {
253
- /**
254
- * @param message - Optional error message
255
- * @param validationErrors - Object containing field-specific validation errors
256
- */
257
- constructor(message?: string, validationErrors?: any) {
258
- super(422, message, {
259
- details: validationErrors ? { validationErrors } : undefined,
260
- });
261
- }
252
+ /**
253
+ * @param message - Optional error message
254
+ * @param validationErrors - Object containing field-specific validation errors
255
+ */
256
+ constructor(message?: string, validationErrors?: any) {
257
+ super(422, message, {
258
+ details: validationErrors ? { validationErrors } : undefined,
259
+ });
260
+ }
262
261
  }
263
262
 
264
263
  /**
@@ -273,15 +272,15 @@ export class UnprocessableEntityError extends HttpError {
273
272
  * ```
274
273
  */
275
274
  export class TooManyRequestsError extends HttpError {
276
- /**
277
- * @param message - Optional error message
278
- * @param retryAfter - Number of seconds the client should wait before retrying
279
- */
280
- constructor(message?: string, retryAfter?: number) {
281
- super(429, message, {
282
- details: retryAfter ? { retryAfter } : undefined,
283
- });
284
- }
275
+ /**
276
+ * @param message - Optional error message
277
+ * @param retryAfter - Number of seconds the client should wait before retrying
278
+ */
279
+ constructor(message?: string, retryAfter?: number) {
280
+ super(429, message, {
281
+ details: retryAfter ? { retryAfter } : undefined,
282
+ });
283
+ }
285
284
  }
286
285
 
287
286
  // Server Error Classes (5xx)
@@ -298,9 +297,9 @@ export class TooManyRequestsError extends HttpError {
298
297
  * ```
299
298
  */
300
299
  export class InternalServerError extends HttpError {
301
- constructor(message?: string, details?: any) {
302
- super(500, message, { details });
303
- }
300
+ constructor(message?: string, details?: any) {
301
+ super(500, message, { details });
302
+ }
304
303
  }
305
304
 
306
305
  /**
@@ -315,9 +314,9 @@ export class InternalServerError extends HttpError {
315
314
  * ```
316
315
  */
317
316
  export class NotImplementedError extends HttpError {
318
- constructor(message?: string, details?: any) {
319
- super(501, message, { details });
320
- }
317
+ constructor(message?: string, details?: any) {
318
+ super(501, message, { details });
319
+ }
321
320
  }
322
321
 
323
322
  /**
@@ -332,9 +331,9 @@ export class NotImplementedError extends HttpError {
332
331
  * ```
333
332
  */
334
333
  export class BadGatewayError extends HttpError {
335
- constructor(message?: string, details?: any) {
336
- super(502, message, { details });
337
- }
334
+ constructor(message?: string, details?: any) {
335
+ super(502, message, { details });
336
+ }
338
337
  }
339
338
 
340
339
  /**
@@ -349,15 +348,15 @@ export class BadGatewayError extends HttpError {
349
348
  * ```
350
349
  */
351
350
  export class ServiceUnavailableError extends HttpError {
352
- /**
353
- * @param message - Optional error message
354
- * @param retryAfter - Number of seconds the client should wait before retrying
355
- */
356
- constructor(message?: string, retryAfter?: number) {
357
- super(503, message, {
358
- details: retryAfter ? { retryAfter } : undefined,
359
- });
360
- }
351
+ /**
352
+ * @param message - Optional error message
353
+ * @param retryAfter - Number of seconds the client should wait before retrying
354
+ */
355
+ constructor(message?: string, retryAfter?: number) {
356
+ super(503, message, {
357
+ details: retryAfter ? { retryAfter } : undefined,
358
+ });
359
+ }
361
360
  }
362
361
 
363
362
  /**
@@ -372,9 +371,9 @@ export class ServiceUnavailableError extends HttpError {
372
371
  * ```
373
372
  */
374
373
  export class GatewayTimeoutError extends HttpError {
375
- constructor(message?: string, details?: any) {
376
- super(504, message, { details });
377
- }
374
+ constructor(message?: string, details?: any) {
375
+ super(504, message, { details });
376
+ }
378
377
  }
379
378
 
380
379
  // Type definitions for different error factory signatures
@@ -383,78 +382,78 @@ export class GatewayTimeoutError extends HttpError {
383
382
  type StandardErrorFactory = (message?: string, details?: any) => HttpError;
384
383
  /** Factory function for Method Not Allowed errors with allowed methods */
385
384
  type MethodNotAllowedFactory = (
386
- message?: string,
387
- allowedMethods?: string[],
385
+ message?: string,
386
+ allowedMethods?: string[],
388
387
  ) => MethodNotAllowedError;
389
388
  /** Factory function for errors that include retry-after information */
390
389
  type RetryAfterFactory = (message?: string, retryAfter?: number) => HttpError;
391
390
  /** Factory function for validation errors with field-specific errors */
392
391
  type ValidationErrorFactory = (
393
- message?: string,
394
- validationErrors?: any,
392
+ message?: string,
393
+ validationErrors?: any,
395
394
  ) => UnprocessableEntityError;
396
395
 
397
396
  /** Discriminated union for all factory types */
398
397
  type ErrorFactory =
399
- | { type: 'standard'; factory: StandardErrorFactory }
400
- | { type: 'methodNotAllowed'; factory: MethodNotAllowedFactory }
401
- | { type: 'retryAfter'; factory: RetryAfterFactory }
402
- | { type: 'validation'; factory: ValidationErrorFactory };
398
+ | { type: 'standard'; factory: StandardErrorFactory }
399
+ | { type: 'methodNotAllowed'; factory: MethodNotAllowedFactory }
400
+ | { type: 'retryAfter'; factory: RetryAfterFactory }
401
+ | { type: 'validation'; factory: ValidationErrorFactory };
403
402
 
404
403
  /** Type-safe error registry mapping status codes to their factory functions */
405
404
  const errorRegistry = {
406
- 400: {
407
- type: 'standard',
408
- factory: (m: string, d: any) => new BadRequestError(m, d),
409
- },
410
- 401: {
411
- type: 'standard',
412
- factory: (m: string, d: any) => new UnauthorizedError(m, d),
413
- },
414
- 403: {
415
- type: 'standard',
416
- factory: (m: string, d: any) => new ForbiddenError(m, d),
417
- },
418
- 404: {
419
- type: 'standard',
420
- factory: (m: string, d: any) => new NotFoundError(m, d),
421
- },
422
- 405: {
423
- type: 'methodNotAllowed',
424
- factory: (m: string, am: string[]) => new MethodNotAllowedError(m, am),
425
- },
426
- 409: {
427
- type: 'standard',
428
- factory: (m: string, d: any) => new ConflictError(m, d),
429
- },
430
- 422: {
431
- type: 'validation',
432
- factory: (m: string, ve: any) => new UnprocessableEntityError(m, ve),
433
- },
434
- 429: {
435
- type: 'retryAfter',
436
- factory: (m: string, ra: number) => new TooManyRequestsError(m, ra),
437
- },
438
- 500: {
439
- type: 'standard',
440
- factory: (m: string, d: any) => new InternalServerError(m, d),
441
- },
442
- 501: {
443
- type: 'standard',
444
- factory: (m: string, d: any) => new NotImplementedError(m, d),
445
- },
446
- 502: {
447
- type: 'standard',
448
- factory: (m: string, d: any) => new BadGatewayError(m, d),
449
- },
450
- 503: {
451
- type: 'retryAfter',
452
- factory: (m: string, ra: number) => new ServiceUnavailableError(m, ra),
453
- },
454
- 504: {
455
- type: 'standard',
456
- factory: (m: string, d: any) => new GatewayTimeoutError(m, d),
457
- },
405
+ 400: {
406
+ type: 'standard',
407
+ factory: (m: string, d: any) => new BadRequestError(m, d),
408
+ },
409
+ 401: {
410
+ type: 'standard',
411
+ factory: (m: string, d: any) => new UnauthorizedError(m, d),
412
+ },
413
+ 403: {
414
+ type: 'standard',
415
+ factory: (m: string, d: any) => new ForbiddenError(m, d),
416
+ },
417
+ 404: {
418
+ type: 'standard',
419
+ factory: (m: string, d: any) => new NotFoundError(m, d),
420
+ },
421
+ 405: {
422
+ type: 'methodNotAllowed',
423
+ factory: (m: string, am: string[]) => new MethodNotAllowedError(m, am),
424
+ },
425
+ 409: {
426
+ type: 'standard',
427
+ factory: (m: string, d: any) => new ConflictError(m, d),
428
+ },
429
+ 422: {
430
+ type: 'validation',
431
+ factory: (m: string, ve: any) => new UnprocessableEntityError(m, ve),
432
+ },
433
+ 429: {
434
+ type: 'retryAfter',
435
+ factory: (m: string, ra: number) => new TooManyRequestsError(m, ra),
436
+ },
437
+ 500: {
438
+ type: 'standard',
439
+ factory: (m: string, d: any) => new InternalServerError(m, d),
440
+ },
441
+ 501: {
442
+ type: 'standard',
443
+ factory: (m: string, d: any) => new NotImplementedError(m, d),
444
+ },
445
+ 502: {
446
+ type: 'standard',
447
+ factory: (m: string, d: any) => new BadGatewayError(m, d),
448
+ },
449
+ 503: {
450
+ type: 'retryAfter',
451
+ factory: (m: string, ra: number) => new ServiceUnavailableError(m, ra),
452
+ },
453
+ 504: {
454
+ type: 'standard',
455
+ factory: (m: string, d: any) => new GatewayTimeoutError(m, d),
456
+ },
458
457
  } as const;
459
458
 
460
459
  /** Valid status codes that have registered error factories */
@@ -462,26 +461,26 @@ type ValidStatusCode = keyof typeof errorRegistry;
462
461
 
463
462
  /** Type-safe options based on status code, ensuring correct parameters for each error type */
464
463
  type ErrorOptions<T extends number> = T extends 405
465
- ? { allowedMethods?: string[]; code?: string; cause?: Error }
466
- : T extends 422
467
- ? { validationErrors?: any; code?: string; cause?: Error }
468
- : T extends 429 | 503
469
- ? { retryAfter?: number; code?: string; cause?: Error }
470
- : { details?: any; code?: string; cause?: Error };
464
+ ? { allowedMethods?: string[]; code?: string; cause?: Error }
465
+ : T extends 422
466
+ ? { validationErrors?: any; code?: string; cause?: Error }
467
+ : T extends 429 | 503
468
+ ? { retryAfter?: number; code?: string; cause?: Error }
469
+ : { details?: any; code?: string; cause?: Error };
471
470
 
472
471
  /** Handler functions for each factory type */
473
472
  const factoryHandlers: Record<
474
- ErrorFactory['type'],
475
- (entry: any, message?: string, options?: any) => HttpError
473
+ ErrorFactory['type'],
474
+ (entry: any, message?: string, options?: any) => HttpError
476
475
  > = {
477
- standard: (entry, message, options) =>
478
- entry.factory(message, options?.details),
479
- methodNotAllowed: (entry, message, options) =>
480
- entry.factory(message, options?.allowedMethods),
481
- retryAfter: (entry, message, options) =>
482
- entry.factory(message, options?.retryAfter),
483
- validation: (entry, message, options) =>
484
- entry.factory(message, options?.validationErrors),
476
+ standard: (entry, message, options) =>
477
+ entry.factory(message, options?.details),
478
+ methodNotAllowed: (entry, message, options) =>
479
+ entry.factory(message, options?.allowedMethods),
480
+ retryAfter: (entry, message, options) =>
481
+ entry.factory(message, options?.retryAfter),
482
+ validation: (entry, message, options) =>
483
+ entry.factory(message, options?.validationErrors),
485
484
  };
486
485
 
487
486
  /**
@@ -504,29 +503,29 @@ const factoryHandlers: Record<
504
503
  * ```
505
504
  */
506
505
  export function createHttpError<T extends ValidStatusCode>(
507
- statusCode: T,
508
- message?: string,
509
- options?: ErrorOptions<T>,
506
+ statusCode: T,
507
+ message?: string,
508
+ options?: ErrorOptions<T>,
510
509
  ): HttpError;
511
510
  export function createHttpError(
512
- statusCode: number,
513
- message?: string,
514
- options?: HttpErrorOptions,
511
+ statusCode: number,
512
+ message?: string,
513
+ options?: HttpErrorOptions,
515
514
  ): HttpError;
516
515
  export function createHttpError(
517
- statusCode: number,
518
- message?: string,
519
- options?: any,
516
+ statusCode: number,
517
+ message?: string,
518
+ options?: any,
520
519
  ): HttpError {
521
- const entry = errorRegistry[statusCode as ValidStatusCode];
520
+ const entry = errorRegistry[statusCode as ValidStatusCode];
522
521
 
523
- if (entry) {
524
- const handler = factoryHandlers[entry.type];
525
- return handler(entry, message, options);
526
- }
522
+ if (entry) {
523
+ const handler = factoryHandlers[entry.type];
524
+ return handler(entry, message, options);
525
+ }
527
526
 
528
- // Fallback to generic HttpError for unknown status codes
529
- return new HttpError(statusCode, message, options);
527
+ // Fallback to generic HttpError for unknown status codes
528
+ return new HttpError(statusCode, message, options);
530
529
  }
531
530
 
532
531
  /**
@@ -541,44 +540,44 @@ export function createHttpError(
541
540
  * ```
542
541
  */
543
542
  export const createError = {
544
- badRequest: (message?: string, details?: any) =>
545
- new BadRequestError(message, details),
543
+ badRequest: (message?: string, details?: any) =>
544
+ new BadRequestError(message, details),
546
545
 
547
- unauthorized: (message?: string, details?: any) =>
548
- new UnauthorizedError(message, details),
546
+ unauthorized: (message?: string, details?: any) =>
547
+ new UnauthorizedError(message, details),
549
548
 
550
- forbidden: (message?: string, details?: any) =>
551
- new ForbiddenError(message, details),
549
+ forbidden: (message?: string, details?: any) =>
550
+ new ForbiddenError(message, details),
552
551
 
553
- notFound: (message?: string, details?: any) =>
554
- new NotFoundError(message, details),
552
+ notFound: (message?: string, details?: any) =>
553
+ new NotFoundError(message, details),
555
554
 
556
- methodNotAllowed: (message?: string, allowedMethods?: string[]) =>
557
- new MethodNotAllowedError(message, allowedMethods),
555
+ methodNotAllowed: (message?: string, allowedMethods?: string[]) =>
556
+ new MethodNotAllowedError(message, allowedMethods),
558
557
 
559
- conflict: (message?: string, details?: any) =>
560
- new ConflictError(message, details),
558
+ conflict: (message?: string, details?: any) =>
559
+ new ConflictError(message, details),
561
560
 
562
- unprocessableEntity: (message?: string, validationErrors?: any) =>
563
- new UnprocessableEntityError(message, validationErrors),
561
+ unprocessableEntity: (message?: string, validationErrors?: any) =>
562
+ new UnprocessableEntityError(message, validationErrors),
564
563
 
565
- tooManyRequests: (message?: string, retryAfter?: number) =>
566
- new TooManyRequestsError(message, retryAfter),
564
+ tooManyRequests: (message?: string, retryAfter?: number) =>
565
+ new TooManyRequestsError(message, retryAfter),
567
566
 
568
- internalServerError: (message?: string, details?: any) =>
569
- new InternalServerError(message, details),
567
+ internalServerError: (message?: string, details?: any) =>
568
+ new InternalServerError(message, details),
570
569
 
571
- notImplemented: (message?: string, details?: any) =>
572
- new NotImplementedError(message, details),
570
+ notImplemented: (message?: string, details?: any) =>
571
+ new NotImplementedError(message, details),
573
572
 
574
- badGateway: (message?: string, details?: any) =>
575
- new BadGatewayError(message, details),
573
+ badGateway: (message?: string, details?: any) =>
574
+ new BadGatewayError(message, details),
576
575
 
577
- serviceUnavailable: (message?: string, retryAfter?: number) =>
578
- new ServiceUnavailableError(message, retryAfter),
576
+ serviceUnavailable: (message?: string, retryAfter?: number) =>
577
+ new ServiceUnavailableError(message, retryAfter),
579
578
 
580
- gatewayTimeout: (message?: string, details?: any) =>
581
- new GatewayTimeoutError(message, details),
579
+ gatewayTimeout: (message?: string, details?: any) =>
580
+ new GatewayTimeoutError(message, details),
582
581
  } as const;
583
582
 
584
583
  // Type guards
@@ -602,13 +601,13 @@ export const createError = {
602
601
  * ```
603
602
  */
604
603
  export function isHttpError(error: unknown): error is HttpError {
605
- return (
606
- error instanceof HttpError ||
607
- (error !== null &&
608
- typeof error === 'object' &&
609
- 'isHttpError' in error &&
610
- error.isHttpError === true)
611
- );
604
+ return (
605
+ error instanceof HttpError ||
606
+ (error !== null &&
607
+ typeof error === 'object' &&
608
+ 'isHttpError' in error &&
609
+ error.isHttpError === true)
610
+ );
612
611
  }
613
612
 
614
613
  /**
@@ -625,9 +624,9 @@ export function isHttpError(error: unknown): error is HttpError {
625
624
  * ```
626
625
  */
627
626
  export function isClientError(error: unknown): error is HttpError {
628
- return (
629
- isHttpError(error) && error.statusCode >= 400 && error.statusCode < 500
630
- );
627
+ return (
628
+ isHttpError(error) && error.statusCode >= 400 && error.statusCode < 500
629
+ );
631
630
  }
632
631
 
633
632
  /**
@@ -644,9 +643,9 @@ export function isClientError(error: unknown): error is HttpError {
644
643
  * ```
645
644
  */
646
645
  export function isServerError(error: unknown): error is HttpError {
647
- return (
648
- isHttpError(error) && error.statusCode >= 500 && error.statusCode < 600
649
- );
646
+ return (
647
+ isHttpError(error) && error.statusCode >= 500 && error.statusCode < 600
648
+ );
650
649
  }
651
650
 
652
651
  // Utility functions
@@ -670,21 +669,21 @@ export function isServerError(error: unknown): error is HttpError {
670
669
  * ```
671
670
  */
672
671
  export function wrapError(
673
- error: unknown,
674
- statusCode = 500,
675
- message?: string,
672
+ error: unknown,
673
+ statusCode = 500,
674
+ message?: string,
676
675
  ): HttpError {
677
- if (isHttpError(error)) {
678
- return error;
679
- }
676
+ if (isHttpError(error)) {
677
+ return error;
678
+ }
680
679
 
681
- if (error instanceof HttpError) {
682
- return error;
683
- }
680
+ if (error instanceof HttpError) {
681
+ return error;
682
+ }
684
683
 
685
- return new HttpError(statusCode, message || 'An unknown error occurred', {
686
- details: { originalError: error },
687
- });
684
+ return new HttpError(statusCode, message || 'An unknown error occurred', {
685
+ details: { originalError: error },
686
+ });
688
687
  }
689
688
 
690
689
  // Types for better TypeScript support
@@ -693,10 +692,10 @@ export function wrapError(
693
692
  * Options for creating an HttpError.
694
693
  */
695
694
  export interface HttpErrorOptions {
696
- statusMessage?: string;
697
- details?: any;
698
- code?: string;
699
- cause?: Error;
695
+ statusMessage?: string;
696
+ details?: any;
697
+ code?: string;
698
+ cause?: Error;
700
699
  }
701
700
 
702
701
  /**
@@ -704,8 +703,8 @@ export interface HttpErrorOptions {
704
703
  * Useful for factory patterns and dependency injection.
705
704
  */
706
705
  export type HttpErrorConstructor = new (
707
- message?: string,
708
- options?: HttpErrorOptions,
706
+ message?: string,
707
+ options?: HttpErrorOptions,
709
708
  ) => HttpError;
710
709
 
711
710
  /**
@@ -713,36 +712,36 @@ export type HttpErrorConstructor = new (
713
712
  * Includes common 2xx, 3xx, 4xx, and 5xx status codes.
714
713
  */
715
714
  export enum HttpStatusCode {
716
- // 2xx Success
717
- OK = 200,
718
- CREATED = 201,
719
- ACCEPTED = 202,
720
- NO_CONTENT = 204,
721
-
722
- // 3xx Redirection
723
- MOVED_PERMANENTLY = 301,
724
- FOUND = 302,
725
- NOT_MODIFIED = 304,
726
-
727
- // 4xx Client Error
728
- BAD_REQUEST = 400,
729
- UNAUTHORIZED = 401,
730
- FORBIDDEN = 403,
731
- NOT_FOUND = 404,
732
- METHOD_NOT_ALLOWED = 405,
733
- NOT_ACCEPTABLE = 406,
734
- REQUEST_TIMEOUT = 408,
735
- CONFLICT = 409,
736
- GONE = 410,
737
- UNPROCESSABLE_ENTITY = 422,
738
- TOO_MANY_REQUESTS = 429,
739
-
740
- // 5xx Server Error
741
- INTERNAL_SERVER_ERROR = 500,
742
- NOT_IMPLEMENTED = 501,
743
- BAD_GATEWAY = 502,
744
- SERVICE_UNAVAILABLE = 503,
745
- GATEWAY_TIMEOUT = 504,
715
+ // 2xx Success
716
+ OK = 200,
717
+ CREATED = 201,
718
+ ACCEPTED = 202,
719
+ NO_CONTENT = 204,
720
+
721
+ // 3xx Redirection
722
+ MOVED_PERMANENTLY = 301,
723
+ FOUND = 302,
724
+ NOT_MODIFIED = 304,
725
+
726
+ // 4xx Client Error
727
+ BAD_REQUEST = 400,
728
+ UNAUTHORIZED = 401,
729
+ FORBIDDEN = 403,
730
+ NOT_FOUND = 404,
731
+ METHOD_NOT_ALLOWED = 405,
732
+ NOT_ACCEPTABLE = 406,
733
+ REQUEST_TIMEOUT = 408,
734
+ CONFLICT = 409,
735
+ GONE = 410,
736
+ UNPROCESSABLE_ENTITY = 422,
737
+ TOO_MANY_REQUESTS = 429,
738
+
739
+ // 5xx Server Error
740
+ INTERNAL_SERVER_ERROR = 500,
741
+ NOT_IMPLEMENTED = 501,
742
+ BAD_GATEWAY = 502,
743
+ SERVICE_UNAVAILABLE = 503,
744
+ GATEWAY_TIMEOUT = 504,
746
745
  }
747
746
 
748
747
  /**
@@ -756,20 +755,20 @@ export enum HttpStatusCode {
756
755
  * ```
757
756
  */
758
757
  export const HttpErrors = {
759
- HttpError,
760
- BadRequestError,
761
- UnauthorizedError,
762
- ForbiddenError,
763
- NotFoundError,
764
- MethodNotAllowedError,
765
- ConflictError,
766
- UnprocessableEntityError,
767
- TooManyRequestsError,
768
- InternalServerError,
769
- NotImplementedError,
770
- BadGatewayError,
771
- ServiceUnavailableError,
772
- GatewayTimeoutError,
758
+ HttpError,
759
+ BadRequestError,
760
+ UnauthorizedError,
761
+ ForbiddenError,
762
+ NotFoundError,
763
+ MethodNotAllowedError,
764
+ ConflictError,
765
+ UnprocessableEntityError,
766
+ TooManyRequestsError,
767
+ InternalServerError,
768
+ NotImplementedError,
769
+ BadGatewayError,
770
+ ServiceUnavailableError,
771
+ GatewayTimeoutError,
773
772
  };
774
773
 
775
774
  // Usage examples: