@nextrush/errors 3.0.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.
@@ -0,0 +1,583 @@
1
+ import { Context, Middleware, Next } from '@nextrush/types';
2
+
3
+ /**
4
+ * @nextrush/errors - Base Error Classes
5
+ *
6
+ * Foundational error classes for NextRush framework.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ /**
11
+ * Base error class for all NextRush errors
12
+ */
13
+ declare class NextRushError extends Error {
14
+ /** HTTP status code */
15
+ readonly status: number;
16
+ /** Error code for programmatic handling */
17
+ readonly code: string;
18
+ /** Whether error message is safe to expose to client */
19
+ readonly expose: boolean;
20
+ /** Additional error details */
21
+ readonly details?: Record<string, unknown>;
22
+ /** Original error that caused this error */
23
+ readonly cause?: unknown;
24
+ constructor(message: string, options?: {
25
+ status?: number;
26
+ code?: string;
27
+ expose?: boolean;
28
+ details?: Record<string, unknown>;
29
+ cause?: unknown;
30
+ });
31
+ /**
32
+ * Convert error to JSON representation
33
+ */
34
+ toJSON(): Record<string, unknown>;
35
+ /**
36
+ * Create a response-safe version of the error
37
+ */
38
+ toResponse(): {
39
+ status: number;
40
+ body: Record<string, unknown>;
41
+ };
42
+ }
43
+ /**
44
+ * Get default message for an HTTP status code
45
+ */
46
+ declare function getHttpStatusMessage(status: number): string;
47
+ /**
48
+ * Base class for HTTP errors
49
+ */
50
+ declare class HttpError extends NextRushError {
51
+ constructor(status: number, message?: string, options?: {
52
+ code?: string;
53
+ expose?: boolean;
54
+ details?: Record<string, unknown>;
55
+ cause?: unknown;
56
+ });
57
+ }
58
+
59
+ /**
60
+ * @nextrush/errors - HTTP Error Classes
61
+ *
62
+ * Standard HTTP error classes for common status codes.
63
+ *
64
+ * @packageDocumentation
65
+ */
66
+
67
+ /**
68
+ * Options for creating HTTP errors
69
+ */
70
+ interface HttpErrorOptions {
71
+ code?: string;
72
+ expose?: boolean;
73
+ details?: Record<string, unknown>;
74
+ cause?: unknown;
75
+ }
76
+ /**
77
+ * 400 Bad Request - Invalid syntax or malformed request
78
+ */
79
+ declare class BadRequestError extends HttpError {
80
+ constructor(message?: string, options?: HttpErrorOptions);
81
+ }
82
+ /**
83
+ * 401 Unauthorized - Authentication required
84
+ */
85
+ declare class UnauthorizedError extends HttpError {
86
+ constructor(message?: string, options?: HttpErrorOptions);
87
+ }
88
+ /**
89
+ * 402 Payment Required - Payment needed
90
+ */
91
+ declare class PaymentRequiredError extends HttpError {
92
+ constructor(message?: string, options?: HttpErrorOptions);
93
+ }
94
+ /**
95
+ * 403 Forbidden - Access denied
96
+ */
97
+ declare class ForbiddenError extends HttpError {
98
+ constructor(message?: string, options?: HttpErrorOptions);
99
+ }
100
+ /**
101
+ * 404 Not Found - Resource not found
102
+ */
103
+ declare class NotFoundError extends HttpError {
104
+ constructor(message?: string, options?: HttpErrorOptions);
105
+ }
106
+ /**
107
+ * 405 Method Not Allowed - HTTP method not supported
108
+ */
109
+ declare class MethodNotAllowedError extends HttpError {
110
+ readonly allowedMethods: string[];
111
+ constructor(allowedMethods?: string[], message?: string, options?: HttpErrorOptions);
112
+ }
113
+ /**
114
+ * 406 Not Acceptable - Cannot produce acceptable response
115
+ */
116
+ declare class NotAcceptableError extends HttpError {
117
+ constructor(message?: string, options?: HttpErrorOptions);
118
+ }
119
+ /**
120
+ * 407 Proxy Authentication Required
121
+ */
122
+ declare class ProxyAuthRequiredError extends HttpError {
123
+ constructor(message?: string, options?: HttpErrorOptions);
124
+ }
125
+ /**
126
+ * 408 Request Timeout - Client took too long
127
+ */
128
+ declare class RequestTimeoutError extends HttpError {
129
+ constructor(message?: string, options?: HttpErrorOptions);
130
+ }
131
+ /**
132
+ * 409 Conflict - Request conflicts with current state
133
+ */
134
+ declare class ConflictError extends HttpError {
135
+ constructor(message?: string, options?: HttpErrorOptions);
136
+ }
137
+ /**
138
+ * 410 Gone - Resource permanently deleted
139
+ */
140
+ declare class GoneError extends HttpError {
141
+ constructor(message?: string, options?: HttpErrorOptions);
142
+ }
143
+ /**
144
+ * 411 Length Required - Content-Length header required
145
+ */
146
+ declare class LengthRequiredError extends HttpError {
147
+ constructor(message?: string, options?: HttpErrorOptions);
148
+ }
149
+ /**
150
+ * 412 Precondition Failed - Precondition in headers not met
151
+ */
152
+ declare class PreconditionFailedError extends HttpError {
153
+ constructor(message?: string, options?: HttpErrorOptions);
154
+ }
155
+ /**
156
+ * 413 Payload Too Large - Request body too large
157
+ */
158
+ declare class PayloadTooLargeError extends HttpError {
159
+ constructor(message?: string, options?: HttpErrorOptions);
160
+ }
161
+ /**
162
+ * 414 URI Too Long - Request URI too long
163
+ */
164
+ declare class UriTooLongError extends HttpError {
165
+ constructor(message?: string, options?: HttpErrorOptions);
166
+ }
167
+ /**
168
+ * 415 Unsupported Media Type - Content type not supported
169
+ */
170
+ declare class UnsupportedMediaTypeError extends HttpError {
171
+ constructor(message?: string, options?: HttpErrorOptions);
172
+ }
173
+ /**
174
+ * 416 Range Not Satisfiable - Cannot satisfy Range header
175
+ */
176
+ declare class RangeNotSatisfiableError extends HttpError {
177
+ constructor(message?: string, options?: HttpErrorOptions);
178
+ }
179
+ /**
180
+ * 417 Expectation Failed - Cannot meet Expect header
181
+ */
182
+ declare class ExpectationFailedError extends HttpError {
183
+ constructor(message?: string, options?: HttpErrorOptions);
184
+ }
185
+ /**
186
+ * 418 I'm a Teapot - RFC 2324
187
+ */
188
+ declare class ImATeapotError extends HttpError {
189
+ constructor(message?: string, options?: HttpErrorOptions);
190
+ }
191
+ /**
192
+ * 422 Unprocessable Entity - Semantic errors
193
+ */
194
+ declare class UnprocessableEntityError extends HttpError {
195
+ constructor(message?: string, options?: HttpErrorOptions);
196
+ }
197
+ /**
198
+ * 423 Locked - Resource is locked
199
+ */
200
+ declare class LockedError extends HttpError {
201
+ constructor(message?: string, options?: HttpErrorOptions);
202
+ }
203
+ /**
204
+ * 424 Failed Dependency - Dependent request failed
205
+ */
206
+ declare class FailedDependencyError extends HttpError {
207
+ constructor(message?: string, options?: HttpErrorOptions);
208
+ }
209
+ /**
210
+ * 425 Too Early - Request replayed too early
211
+ */
212
+ declare class TooEarlyError extends HttpError {
213
+ constructor(message?: string, options?: HttpErrorOptions);
214
+ }
215
+ /**
216
+ * 426 Upgrade Required - Client should upgrade protocol
217
+ */
218
+ declare class UpgradeRequiredError extends HttpError {
219
+ constructor(message?: string, options?: HttpErrorOptions);
220
+ }
221
+ /**
222
+ * 428 Precondition Required - Origin server requires conditional request
223
+ */
224
+ declare class PreconditionRequiredError extends HttpError {
225
+ constructor(message?: string, options?: HttpErrorOptions);
226
+ }
227
+ /**
228
+ * 429 Too Many Requests - Rate limit exceeded
229
+ */
230
+ declare class TooManyRequestsError extends HttpError {
231
+ readonly retryAfter?: number;
232
+ constructor(message?: string, options?: HttpErrorOptions & {
233
+ retryAfter?: number;
234
+ });
235
+ }
236
+ /**
237
+ * 431 Request Header Fields Too Large
238
+ */
239
+ declare class RequestHeaderFieldsTooLargeError extends HttpError {
240
+ constructor(message?: string, options?: HttpErrorOptions);
241
+ }
242
+ /**
243
+ * 451 Unavailable For Legal Reasons
244
+ */
245
+ declare class UnavailableForLegalReasonsError extends HttpError {
246
+ constructor(message?: string, options?: HttpErrorOptions);
247
+ }
248
+ /**
249
+ * 500 Internal Server Error - Generic server error
250
+ */
251
+ declare class InternalServerError extends HttpError {
252
+ constructor(message?: string, options?: HttpErrorOptions);
253
+ }
254
+ /**
255
+ * 501 Not Implemented - Feature not implemented
256
+ */
257
+ declare class NotImplementedError extends HttpError {
258
+ constructor(message?: string, options?: HttpErrorOptions);
259
+ }
260
+ /**
261
+ * 502 Bad Gateway - Invalid upstream response
262
+ */
263
+ declare class BadGatewayError extends HttpError {
264
+ constructor(message?: string, options?: HttpErrorOptions);
265
+ }
266
+ /**
267
+ * 503 Service Unavailable - Server temporarily unavailable
268
+ */
269
+ declare class ServiceUnavailableError extends HttpError {
270
+ readonly retryAfter?: number;
271
+ constructor(message?: string, options?: HttpErrorOptions & {
272
+ retryAfter?: number;
273
+ });
274
+ }
275
+ /**
276
+ * 504 Gateway Timeout - Upstream timeout
277
+ */
278
+ declare class GatewayTimeoutError extends HttpError {
279
+ constructor(message?: string, options?: HttpErrorOptions);
280
+ }
281
+ /**
282
+ * 505 HTTP Version Not Supported
283
+ */
284
+ declare class HttpVersionNotSupportedError extends HttpError {
285
+ constructor(message?: string, options?: HttpErrorOptions);
286
+ }
287
+ /**
288
+ * 506 Variant Also Negotiates
289
+ */
290
+ declare class VariantAlsoNegotiatesError extends HttpError {
291
+ constructor(message?: string, options?: HttpErrorOptions);
292
+ }
293
+ /**
294
+ * 507 Insufficient Storage
295
+ */
296
+ declare class InsufficientStorageError extends HttpError {
297
+ constructor(message?: string, options?: HttpErrorOptions);
298
+ }
299
+ /**
300
+ * 508 Loop Detected
301
+ */
302
+ declare class LoopDetectedError extends HttpError {
303
+ constructor(message?: string, options?: HttpErrorOptions);
304
+ }
305
+ /**
306
+ * 510 Not Extended
307
+ */
308
+ declare class NotExtendedError extends HttpError {
309
+ constructor(message?: string, options?: HttpErrorOptions);
310
+ }
311
+ /**
312
+ * 511 Network Authentication Required
313
+ */
314
+ declare class NetworkAuthRequiredError extends HttpError {
315
+ constructor(message?: string, options?: HttpErrorOptions);
316
+ }
317
+
318
+ /**
319
+ * @nextrush/errors - Validation Error Classes
320
+ *
321
+ * Specialized errors for input validation.
322
+ *
323
+ * @packageDocumentation
324
+ */
325
+
326
+ /**
327
+ * Single validation issue
328
+ */
329
+ interface ValidationIssue {
330
+ /** Field path (e.g., 'user.email' or 'items[0].name') */
331
+ path: string;
332
+ /** Error message for this field */
333
+ message: string;
334
+ /** Validation rule that failed */
335
+ rule?: string;
336
+ /** Expected value or constraint */
337
+ expected?: unknown;
338
+ /** Actual value received */
339
+ received?: unknown;
340
+ }
341
+ /**
342
+ * Validation error with multiple issues
343
+ */
344
+ declare class ValidationError extends NextRushError {
345
+ /** List of validation issues */
346
+ readonly issues: ValidationIssue[];
347
+ constructor(issues: ValidationIssue[], message?: string);
348
+ /**
349
+ * Create from a single field error
350
+ */
351
+ static fromField(path: string, message: string, rule?: string): ValidationError;
352
+ /**
353
+ * Create from multiple field errors
354
+ */
355
+ static fromFields(errors: Record<string, string>): ValidationError;
356
+ /**
357
+ * Check if a specific field has errors
358
+ */
359
+ hasErrorFor(path: string): boolean;
360
+ /**
361
+ * Get errors for a specific field
362
+ */
363
+ getErrorsFor(path: string): ValidationIssue[];
364
+ /**
365
+ * Get first error message for a field
366
+ */
367
+ getFirstError(path: string): string | undefined;
368
+ /**
369
+ * Convert to flat error object
370
+ */
371
+ toFlatObject(): Record<string, string>;
372
+ toJSON(): Record<string, unknown>;
373
+ }
374
+ /**
375
+ * Required field missing
376
+ */
377
+ declare class RequiredFieldError extends ValidationError {
378
+ constructor(field: string);
379
+ }
380
+ /**
381
+ * Field type mismatch
382
+ */
383
+ declare class TypeMismatchError extends ValidationError {
384
+ constructor(field: string, expected: string, received: string);
385
+ }
386
+ /**
387
+ * Value out of range
388
+ */
389
+ declare class RangeValidationError extends ValidationError {
390
+ constructor(field: string, min?: number, max?: number);
391
+ }
392
+ /**
393
+ * String length violation
394
+ */
395
+ declare class LengthError extends ValidationError {
396
+ constructor(field: string, min?: number, max?: number);
397
+ }
398
+ /**
399
+ * Pattern mismatch
400
+ */
401
+ declare class PatternError extends ValidationError {
402
+ constructor(field: string, pattern: string, message?: string);
403
+ }
404
+ /**
405
+ * Invalid email format
406
+ */
407
+ declare class InvalidEmailError extends ValidationError {
408
+ constructor(field?: string);
409
+ }
410
+ /**
411
+ * Invalid URL format
412
+ */
413
+ declare class InvalidUrlError extends ValidationError {
414
+ constructor(field?: string);
415
+ }
416
+
417
+ /**
418
+ * @nextrush/errors - Error Factory
419
+ *
420
+ * Factory functions for creating errors.
421
+ *
422
+ * @packageDocumentation
423
+ */
424
+
425
+ /**
426
+ * Create an HTTP error by status code
427
+ */
428
+ declare function createError(status: number, message?: string, options?: HttpErrorOptions): HttpError;
429
+ /**
430
+ * Create a 400 Bad Request error
431
+ */
432
+ declare function badRequest(message?: string, options?: HttpErrorOptions): BadRequestError;
433
+ /**
434
+ * Create a 401 Unauthorized error
435
+ */
436
+ declare function unauthorized(message?: string, options?: HttpErrorOptions): UnauthorizedError;
437
+ /**
438
+ * Create a 403 Forbidden error
439
+ */
440
+ declare function forbidden(message?: string, options?: HttpErrorOptions): ForbiddenError;
441
+ /**
442
+ * Create a 404 Not Found error
443
+ */
444
+ declare function notFound(message?: string, options?: HttpErrorOptions): NotFoundError;
445
+ /**
446
+ * Create a 405 Method Not Allowed error
447
+ */
448
+ declare function methodNotAllowed(allowedMethods?: string[], message?: string, options?: HttpErrorOptions): MethodNotAllowedError;
449
+ /**
450
+ * Create a 409 Conflict error
451
+ */
452
+ declare function conflict(message?: string, options?: HttpErrorOptions): ConflictError;
453
+ /**
454
+ * Create a 422 Unprocessable Entity error
455
+ */
456
+ declare function unprocessableEntity(message?: string, options?: HttpErrorOptions): UnprocessableEntityError;
457
+ /**
458
+ * Create a 429 Too Many Requests error
459
+ */
460
+ declare function tooManyRequests(message?: string, options?: HttpErrorOptions & {
461
+ retryAfter?: number;
462
+ }): TooManyRequestsError;
463
+ /**
464
+ * Create a 500 Internal Server Error
465
+ */
466
+ declare function internalError(message?: string, options?: HttpErrorOptions): InternalServerError;
467
+ /**
468
+ * Create a 502 Bad Gateway error
469
+ */
470
+ declare function badGateway(message?: string, options?: HttpErrorOptions): BadGatewayError;
471
+ /**
472
+ * Create a 503 Service Unavailable error
473
+ */
474
+ declare function serviceUnavailable(message?: string, options?: HttpErrorOptions & {
475
+ retryAfter?: number;
476
+ }): ServiceUnavailableError;
477
+ /**
478
+ * Create a 504 Gateway Timeout error
479
+ */
480
+ declare function gatewayTimeout(message?: string, options?: HttpErrorOptions): GatewayTimeoutError;
481
+ /**
482
+ * Check if an error is a NextRush HttpError
483
+ */
484
+ declare function isHttpError(error: unknown): error is HttpError;
485
+ /**
486
+ * Get HTTP status from any error
487
+ *
488
+ * Checks NextRushError first (covers HttpError, ValidationError, and all subclasses),
489
+ * then falls back to duck-typed status property.
490
+ */
491
+ declare function getErrorStatus(error: unknown): number;
492
+ /**
493
+ * Get error message safe for client response
494
+ *
495
+ * Exposes message for any NextRushError (including ValidationError)
496
+ * when the error's expose flag is true.
497
+ */
498
+ declare function getSafeErrorMessage(error: unknown): string;
499
+
500
+ /**
501
+ * @nextrush/errors - Error Handler Middleware
502
+ *
503
+ * Middleware for handling errors in NextRush applications.
504
+ *
505
+ * @packageDocumentation
506
+ */
507
+
508
+ /**
509
+ * Minimal context interface for error handling.
510
+ *
511
+ * @deprecated Use `Context` from `@nextrush/types` instead.
512
+ * Kept for backward compatibility — will be removed in v4.
513
+ */
514
+ interface ErrorContext {
515
+ method: string;
516
+ path: string;
517
+ status: number;
518
+ json: (data: unknown) => void;
519
+ }
520
+ /**
521
+ * Error handler middleware function type.
522
+ *
523
+ * @deprecated Use `Middleware` from `@nextrush/types` instead.
524
+ * Kept for backward compatibility — will be removed in v4.
525
+ */
526
+ type ErrorMiddleware = Middleware;
527
+ /**
528
+ * Error handler options
529
+ */
530
+ interface ErrorHandlerOptions {
531
+ /** Include stack trace in development */
532
+ includeStack?: boolean;
533
+ /** Custom error logger */
534
+ logger?: (error: Error, ctx: Context) => void;
535
+ /** Custom error transformer */
536
+ transform?: (error: Error, ctx: Context) => Record<string, unknown>;
537
+ /** Handle specific error types */
538
+ handlers?: Map<new (...args: unknown[]) => Error, (error: Error, ctx: Context) => void>;
539
+ }
540
+ /**
541
+ * Create error handler middleware
542
+ *
543
+ * @example
544
+ * ```typescript
545
+ * const app = createApp();
546
+ *
547
+ * // Add error handler first
548
+ * app.use(errorHandler({
549
+ * includeStack: process.env.NODE_ENV !== 'production',
550
+ * logger: (err, ctx) => myLogger.error(err),
551
+ * }));
552
+ * ```
553
+ */
554
+ declare function errorHandler(options?: ErrorHandlerOptions): Middleware;
555
+ /**
556
+ * Not found handler middleware - catches unhandled requests
557
+ *
558
+ * @example
559
+ * ```typescript
560
+ * // Add at the end of middleware chain
561
+ * app.use(notFoundHandler());
562
+ * ```
563
+ */
564
+ declare function notFoundHandler(message?: string): Middleware;
565
+ /**
566
+ * Catch async errors wrapper for route handlers
567
+ *
568
+ * @example
569
+ * ```typescript
570
+ * router.get('/users/:id', catchAsync(async (ctx) => {
571
+ * const user = await db.users.findById(ctx.params.id);
572
+ * if (!user) throw new NotFoundError('User not found');
573
+ * ctx.json(user);
574
+ * }));
575
+ * ```
576
+ *
577
+ * @deprecated This wrapper is redundant — async errors propagate naturally
578
+ * through the middleware chain and are caught by `errorHandler()`. Use the
579
+ * handler directly instead.
580
+ */
581
+ declare function catchAsync(handler: (ctx: Context, next: Next) => Promise<void>): Middleware;
582
+
583
+ export { BadGatewayError, BadRequestError, ConflictError, type ErrorContext, type ErrorHandlerOptions, type ErrorMiddleware, ExpectationFailedError, FailedDependencyError, ForbiddenError, GatewayTimeoutError, GoneError, HttpError, type HttpErrorOptions, HttpVersionNotSupportedError, ImATeapotError, InsufficientStorageError, InternalServerError, InvalidEmailError, InvalidUrlError, LengthError, LengthRequiredError, LockedError, LoopDetectedError, MethodNotAllowedError, NetworkAuthRequiredError, NextRushError, NotAcceptableError, NotExtendedError, NotFoundError, NotImplementedError, PatternError, PayloadTooLargeError, PaymentRequiredError, PreconditionFailedError, PreconditionRequiredError, ProxyAuthRequiredError, RangeNotSatisfiableError, RangeValidationError, RequestHeaderFieldsTooLargeError, RequestTimeoutError, RequiredFieldError, ServiceUnavailableError, TooEarlyError, TooManyRequestsError, TypeMismatchError, UnauthorizedError, UnavailableForLegalReasonsError, UnprocessableEntityError, UnsupportedMediaTypeError, UpgradeRequiredError, UriTooLongError, ValidationError, type ValidationIssue, VariantAlsoNegotiatesError, badGateway, badRequest, catchAsync, conflict, createError, errorHandler, forbidden, gatewayTimeout, getErrorStatus, getHttpStatusMessage, getSafeErrorMessage, internalError, isHttpError, methodNotAllowed, notFound, notFoundHandler, serviceUnavailable, tooManyRequests, unauthorized, unprocessableEntity };