@nextrush/errors 3.0.6 → 4.0.0-beta.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/base.ts","../src/http-errors.ts","../src/validation.ts","../src/factory.ts","../src/middleware.ts"],"sourcesContent":["/**\n * @nextrush/errors - Base Error Classes\n *\n * Foundational error classes for NextRush framework.\n *\n * @packageDocumentation\n */\n\nconst V8Error = Error as ErrorConstructor & {\n captureStackTrace?: (targetObject: object, constructorOpt?: Function) => void;\n};\n\n/**\n * Base error class for all NextRush errors\n */\nexport class NextRushError extends Error {\n /** HTTP status code */\n readonly status: number;\n\n /** Error code for programmatic handling */\n readonly code: string;\n\n /** Whether error message is safe to expose to client */\n readonly expose: boolean;\n\n /** Additional error details */\n readonly details?: Record<string, unknown>;\n\n /** Original error that caused this error */\n readonly cause?: unknown;\n\n constructor(\n message: string,\n options: {\n status?: number;\n code?: string;\n expose?: boolean;\n details?: Record<string, unknown>;\n cause?: unknown;\n } = {}\n ) {\n super(message);\n this.name = this.constructor.name;\n this.status = options.status ?? 500;\n this.code = options.code ?? 'INTERNAL_ERROR';\n this.expose = options.expose ?? this.status < 500;\n this.details = options.details;\n this.cause = options.cause;\n\n // Maintain proper stack trace for V8\n // Skip for common client errors (4xx with expose=true) to reduce overhead.\n // These are expected control-flow errors, not bugs — stack traces add cost\n // without diagnostic value in production.\n if (V8Error.captureStackTrace && !(this.expose && this.status < 500)) {\n V8Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Convert error to JSON representation\n */\n toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {\n error: this.name,\n message: this.expose ? this.message : 'Internal Server Error',\n code: this.code,\n status: this.status,\n };\n\n if (this.expose && this.details) {\n json.details = this.details;\n }\n\n return json;\n }\n\n /**\n * Create a response-safe version of the error\n */\n toResponse(): { status: number; body: Record<string, unknown> } {\n return {\n status: this.status,\n body: this.toJSON(),\n };\n }\n}\n\n/**\n * Default HTTP status messages\n */\nconst HTTP_STATUS_MESSAGES: Record<number, string> = {\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 402: 'Payment Required',\n 403: 'Forbidden',\n 404: 'Not Found',\n 405: 'Method Not Allowed',\n 406: 'Not Acceptable',\n 407: 'Proxy Authentication Required',\n 408: 'Request Timeout',\n 409: 'Conflict',\n 410: 'Gone',\n 411: 'Length Required',\n 412: 'Precondition Failed',\n 413: 'Payload Too Large',\n 414: 'URI Too Long',\n 415: 'Unsupported Media Type',\n 416: 'Range Not Satisfiable',\n 417: 'Expectation Failed',\n 418: \"I'm a Teapot\",\n 422: 'Unprocessable Entity',\n 423: 'Locked',\n 424: 'Failed Dependency',\n 425: 'Too Early',\n 426: 'Upgrade Required',\n 428: 'Precondition Required',\n 429: 'Too Many Requests',\n 431: 'Request Header Fields Too Large',\n 451: 'Unavailable For Legal Reasons',\n 500: 'Internal Server Error',\n 501: 'Not Implemented',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n 505: 'HTTP Version Not Supported',\n 506: 'Variant Also Negotiates',\n 507: 'Insufficient Storage',\n 508: 'Loop Detected',\n 510: 'Not Extended',\n 511: 'Network Authentication Required',\n};\n\n/**\n * Get default message for an HTTP status code\n */\nexport function getHttpStatusMessage(status: number): string {\n return HTTP_STATUS_MESSAGES[status] ?? `HTTP Error ${status}`;\n}\n\n/**\n * Base class for HTTP errors\n */\nexport class HttpError extends NextRushError {\n constructor(\n status: number,\n message?: string,\n options: {\n code?: string;\n expose?: boolean;\n details?: Record<string, unknown>;\n cause?: unknown;\n } = {}\n ) {\n super(message ?? getHttpStatusMessage(status), {\n status,\n code: options.code ?? `HTTP_${status}`,\n expose: options.expose ?? status < 500,\n details: options.details,\n cause: options.cause,\n });\n }\n}\n","/**\n * @nextrush/errors - HTTP Error Classes\n *\n * Standard HTTP error classes for common status codes.\n *\n * @packageDocumentation\n */\n\nimport { HttpError } from './base';\n\n/**\n * Options for creating HTTP errors\n */\nexport interface HttpErrorOptions {\n code?: string;\n expose?: boolean;\n details?: Record<string, unknown>;\n cause?: unknown;\n}\n\n// =============================================================================\n// 4xx Client Errors\n// =============================================================================\n\n/**\n * 400 Bad Request - Invalid syntax or malformed request\n */\nexport class BadRequestError extends HttpError {\n constructor(message = 'Bad Request', options: HttpErrorOptions = {}) {\n super(400, message, { code: 'BAD_REQUEST', ...options });\n }\n}\n\n/**\n * 401 Unauthorized - Authentication required\n */\nexport class UnauthorizedError extends HttpError {\n constructor(message = 'Unauthorized', options: HttpErrorOptions = {}) {\n super(401, message, { code: 'UNAUTHORIZED', ...options });\n }\n}\n\n/**\n * 402 Payment Required - Payment needed\n */\nexport class PaymentRequiredError extends HttpError {\n constructor(message = 'Payment Required', options: HttpErrorOptions = {}) {\n super(402, message, { code: 'PAYMENT_REQUIRED', ...options });\n }\n}\n\n/**\n * 403 Forbidden - Access denied\n */\nexport class ForbiddenError extends HttpError {\n constructor(message = 'Forbidden', options: HttpErrorOptions = {}) {\n super(403, message, { code: 'FORBIDDEN', ...options });\n }\n}\n\n/**\n * 404 Not Found - Resource not found\n */\nexport class NotFoundError extends HttpError {\n constructor(message = 'Not Found', options: HttpErrorOptions = {}) {\n super(404, message, { code: 'NOT_FOUND', ...options });\n }\n}\n\n/**\n * 405 Method Not Allowed - HTTP method not supported\n */\nexport class MethodNotAllowedError extends HttpError {\n readonly allowedMethods: string[];\n\n constructor(\n allowedMethods: string[] = [],\n message = 'Method Not Allowed',\n options: HttpErrorOptions = {}\n ) {\n super(405, message, {\n code: 'METHOD_NOT_ALLOWED',\n details: { allowedMethods },\n ...options,\n });\n this.allowedMethods = allowedMethods;\n }\n}\n\n/**\n * 406 Not Acceptable - Cannot produce acceptable response\n */\nexport class NotAcceptableError extends HttpError {\n constructor(message = 'Not Acceptable', options: HttpErrorOptions = {}) {\n super(406, message, { code: 'NOT_ACCEPTABLE', ...options });\n }\n}\n\n/**\n * 407 Proxy Authentication Required\n */\nexport class ProxyAuthRequiredError extends HttpError {\n constructor(message = 'Proxy Authentication Required', options: HttpErrorOptions = {}) {\n super(407, message, { code: 'PROXY_AUTH_REQUIRED', ...options });\n }\n}\n\n/**\n * 408 Request Timeout - Client took too long\n */\nexport class RequestTimeoutError extends HttpError {\n constructor(message = 'Request Timeout', options: HttpErrorOptions = {}) {\n super(408, message, { code: 'REQUEST_TIMEOUT', ...options });\n }\n}\n\n/**\n * 409 Conflict - Request conflicts with current state\n */\nexport class ConflictError extends HttpError {\n constructor(message = 'Conflict', options: HttpErrorOptions = {}) {\n super(409, message, { code: 'CONFLICT', ...options });\n }\n}\n\n/**\n * 410 Gone - Resource permanently deleted\n */\nexport class GoneError extends HttpError {\n constructor(message = 'Gone', options: HttpErrorOptions = {}) {\n super(410, message, { code: 'GONE', ...options });\n }\n}\n\n/**\n * 411 Length Required - Content-Length header required\n */\nexport class LengthRequiredError extends HttpError {\n constructor(message = 'Length Required', options: HttpErrorOptions = {}) {\n super(411, message, { code: 'LENGTH_REQUIRED', ...options });\n }\n}\n\n/**\n * 412 Precondition Failed - Precondition in headers not met\n */\nexport class PreconditionFailedError extends HttpError {\n constructor(message = 'Precondition Failed', options: HttpErrorOptions = {}) {\n super(412, message, { code: 'PRECONDITION_FAILED', ...options });\n }\n}\n\n/**\n * 413 Payload Too Large - Request body too large\n */\nexport class PayloadTooLargeError extends HttpError {\n constructor(message = 'Payload Too Large', options: HttpErrorOptions = {}) {\n super(413, message, { code: 'PAYLOAD_TOO_LARGE', ...options });\n }\n}\n\n/**\n * 414 URI Too Long - Request URI too long\n */\nexport class UriTooLongError extends HttpError {\n constructor(message = 'URI Too Long', options: HttpErrorOptions = {}) {\n super(414, message, { code: 'URI_TOO_LONG', ...options });\n }\n}\n\n/**\n * 415 Unsupported Media Type - Content type not supported\n */\nexport class UnsupportedMediaTypeError extends HttpError {\n constructor(message = 'Unsupported Media Type', options: HttpErrorOptions = {}) {\n super(415, message, { code: 'UNSUPPORTED_MEDIA_TYPE', ...options });\n }\n}\n\n/**\n * 416 Range Not Satisfiable - Cannot satisfy Range header\n */\nexport class RangeNotSatisfiableError extends HttpError {\n constructor(message = 'Range Not Satisfiable', options: HttpErrorOptions = {}) {\n super(416, message, { code: 'RANGE_NOT_SATISFIABLE', ...options });\n }\n}\n\n/**\n * 417 Expectation Failed - Cannot meet Expect header\n */\nexport class ExpectationFailedError extends HttpError {\n constructor(message = 'Expectation Failed', options: HttpErrorOptions = {}) {\n super(417, message, { code: 'EXPECTATION_FAILED', ...options });\n }\n}\n\n/**\n * 418 I'm a Teapot - RFC 2324\n */\nexport class ImATeapotError extends HttpError {\n constructor(message = \"I'm a teapot\", options: HttpErrorOptions = {}) {\n super(418, message, { code: 'IM_A_TEAPOT', ...options });\n }\n}\n\n/**\n * 422 Unprocessable Entity - Semantic errors\n */\nexport class UnprocessableEntityError extends HttpError {\n constructor(message = 'Unprocessable Entity', options: HttpErrorOptions = {}) {\n super(422, message, { code: 'UNPROCESSABLE_ENTITY', ...options });\n }\n}\n\n/**\n * 423 Locked - Resource is locked\n */\nexport class LockedError extends HttpError {\n constructor(message = 'Locked', options: HttpErrorOptions = {}) {\n super(423, message, { code: 'LOCKED', ...options });\n }\n}\n\n/**\n * 424 Failed Dependency - Dependent request failed\n */\nexport class FailedDependencyError extends HttpError {\n constructor(message = 'Failed Dependency', options: HttpErrorOptions = {}) {\n super(424, message, { code: 'FAILED_DEPENDENCY', ...options });\n }\n}\n\n/**\n * 425 Too Early - Request replayed too early\n */\nexport class TooEarlyError extends HttpError {\n constructor(message = 'Too Early', options: HttpErrorOptions = {}) {\n super(425, message, { code: 'TOO_EARLY', ...options });\n }\n}\n\n/**\n * 426 Upgrade Required - Client should upgrade protocol\n */\nexport class UpgradeRequiredError extends HttpError {\n constructor(message = 'Upgrade Required', options: HttpErrorOptions = {}) {\n super(426, message, { code: 'UPGRADE_REQUIRED', ...options });\n }\n}\n\n/**\n * 428 Precondition Required - Origin server requires conditional request\n */\nexport class PreconditionRequiredError extends HttpError {\n constructor(message = 'Precondition Required', options: HttpErrorOptions = {}) {\n super(428, message, { code: 'PRECONDITION_REQUIRED', ...options });\n }\n}\n\n/**\n * 429 Too Many Requests - Rate limit exceeded\n */\nexport class TooManyRequestsError extends HttpError {\n readonly retryAfter?: number;\n\n constructor(\n message = 'Too Many Requests',\n options: HttpErrorOptions & { retryAfter?: number } = {}\n ) {\n super(429, message, {\n code: 'TOO_MANY_REQUESTS',\n details: options.retryAfter ? { retryAfter: options.retryAfter } : undefined,\n ...options,\n });\n this.retryAfter = options.retryAfter;\n }\n}\n\n/**\n * 431 Request Header Fields Too Large\n */\nexport class RequestHeaderFieldsTooLargeError extends HttpError {\n constructor(message = 'Request Header Fields Too Large', options: HttpErrorOptions = {}) {\n super(431, message, { code: 'REQUEST_HEADER_FIELDS_TOO_LARGE', ...options });\n }\n}\n\n/**\n * 451 Unavailable For Legal Reasons\n */\nexport class UnavailableForLegalReasonsError extends HttpError {\n constructor(message = 'Unavailable For Legal Reasons', options: HttpErrorOptions = {}) {\n super(451, message, { code: 'UNAVAILABLE_FOR_LEGAL_REASONS', ...options });\n }\n}\n\n// =============================================================================\n// 5xx Server Errors\n// =============================================================================\n\n/**\n * 500 Internal Server Error - Generic server error\n */\nexport class InternalServerError extends HttpError {\n constructor(message = 'Internal Server Error', options: HttpErrorOptions = {}) {\n super(500, message, { code: 'INTERNAL_SERVER_ERROR', expose: false, ...options });\n }\n}\n\n/**\n * 501 Not Implemented - Feature not implemented\n */\nexport class NotImplementedError extends HttpError {\n constructor(message = 'Not Implemented', options: HttpErrorOptions = {}) {\n super(501, message, { code: 'NOT_IMPLEMENTED', expose: false, ...options });\n }\n}\n\n/**\n * 502 Bad Gateway - Invalid upstream response\n */\nexport class BadGatewayError extends HttpError {\n constructor(message = 'Bad Gateway', options: HttpErrorOptions = {}) {\n super(502, message, { code: 'BAD_GATEWAY', expose: false, ...options });\n }\n}\n\n/**\n * 503 Service Unavailable - Server temporarily unavailable\n */\nexport class ServiceUnavailableError extends HttpError {\n readonly retryAfter?: number;\n\n constructor(\n message = 'Service Unavailable',\n options: HttpErrorOptions & { retryAfter?: number } = {}\n ) {\n super(503, message, {\n code: 'SERVICE_UNAVAILABLE',\n expose: false,\n ...options,\n });\n this.retryAfter = options.retryAfter;\n }\n}\n\n/**\n * 504 Gateway Timeout - Upstream timeout\n */\nexport class GatewayTimeoutError extends HttpError {\n constructor(message = 'Gateway Timeout', options: HttpErrorOptions = {}) {\n super(504, message, { code: 'GATEWAY_TIMEOUT', expose: false, ...options });\n }\n}\n\n/**\n * 505 HTTP Version Not Supported\n */\nexport class HttpVersionNotSupportedError extends HttpError {\n constructor(message = 'HTTP Version Not Supported', options: HttpErrorOptions = {}) {\n super(505, message, { code: 'HTTP_VERSION_NOT_SUPPORTED', expose: false, ...options });\n }\n}\n\n/**\n * 506 Variant Also Negotiates\n */\nexport class VariantAlsoNegotiatesError extends HttpError {\n constructor(message = 'Variant Also Negotiates', options: HttpErrorOptions = {}) {\n super(506, message, { code: 'VARIANT_ALSO_NEGOTIATES', expose: false, ...options });\n }\n}\n\n/**\n * 507 Insufficient Storage\n */\nexport class InsufficientStorageError extends HttpError {\n constructor(message = 'Insufficient Storage', options: HttpErrorOptions = {}) {\n super(507, message, { code: 'INSUFFICIENT_STORAGE', expose: false, ...options });\n }\n}\n\n/**\n * 508 Loop Detected\n */\nexport class LoopDetectedError extends HttpError {\n constructor(message = 'Loop Detected', options: HttpErrorOptions = {}) {\n super(508, message, { code: 'LOOP_DETECTED', expose: false, ...options });\n }\n}\n\n/**\n * 510 Not Extended\n */\nexport class NotExtendedError extends HttpError {\n constructor(message = 'Not Extended', options: HttpErrorOptions = {}) {\n super(510, message, { code: 'NOT_EXTENDED', expose: false, ...options });\n }\n}\n\n/**\n * 511 Network Authentication Required\n */\nexport class NetworkAuthRequiredError extends HttpError {\n constructor(message = 'Network Authentication Required', options: HttpErrorOptions = {}) {\n super(511, message, { code: 'NETWORK_AUTH_REQUIRED', expose: false, ...options });\n }\n}\n","/**\n * @nextrush/errors - Validation Error Classes\n *\n * Specialized errors for input validation.\n *\n * @packageDocumentation\n */\n\nimport { NextRushError } from './base';\n\n/**\n * Single validation issue\n */\nexport interface ValidationIssue {\n /** Field path (e.g., 'user.email' or 'items[0].name') */\n path: string;\n /** Error message for this field */\n message: string;\n /** Validation rule that failed */\n rule?: string;\n /** Expected value or constraint */\n expected?: unknown;\n /** Actual value received */\n received?: unknown;\n}\n\n/**\n * Validation error with multiple issues\n */\nexport class ValidationError extends NextRushError {\n /** List of validation issues */\n readonly issues: ValidationIssue[];\n\n constructor(issues: ValidationIssue[], message = 'Validation failed') {\n super(message, {\n status: 400,\n code: 'VALIDATION_ERROR',\n expose: true,\n });\n this.issues = issues;\n }\n\n /**\n * Create from a single field error\n */\n static fromField(path: string, message: string, rule?: string): ValidationError {\n return new ValidationError([{ path, message, rule }]);\n }\n\n /**\n * Create from multiple field errors\n */\n static fromFields(errors: Record<string, string>): ValidationError {\n const issues = Object.entries(errors).map(([path, message]) => ({\n path,\n message,\n }));\n return new ValidationError(issues);\n }\n\n /**\n * Check if a specific field has errors\n */\n hasErrorFor(path: string): boolean {\n return this.issues.some((issue) => issue.path === path);\n }\n\n /**\n * Get errors for a specific field\n */\n getErrorsFor(path: string): ValidationIssue[] {\n return this.issues.filter((issue) => issue.path === path);\n }\n\n /**\n * Get first error message for a field\n */\n getFirstError(path: string): string | undefined {\n return this.issues.find((issue) => issue.path === path)?.message;\n }\n\n /**\n * Convert to flat error object\n */\n toFlatObject(): Record<string, string> {\n const result: Record<string, string> = {};\n for (const issue of this.issues) {\n if (!result[issue.path]) {\n result[issue.path] = issue.message;\n }\n }\n return result;\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n error: this.name,\n message: this.message,\n code: this.code,\n status: this.status,\n // Strip `received` to prevent leaking sensitive input values (passwords, tokens)\n issues: this.issues.map(({ path, message, rule, expected }) => ({\n path,\n message,\n ...(rule !== undefined && { rule }),\n ...(expected !== undefined && { expected }),\n })),\n };\n }\n}\n\n/**\n * Required field missing\n */\nexport class RequiredFieldError extends ValidationError {\n constructor(field: string) {\n super(\n [{ path: field, message: `${field} is required`, rule: 'required' }],\n `${field} is required`\n );\n }\n}\n\n/**\n * Field type mismatch\n */\nexport class TypeMismatchError extends ValidationError {\n constructor(field: string, expected: string, received: string) {\n super(\n [\n {\n path: field,\n message: `Expected ${expected}, received ${received}`,\n rule: 'type',\n expected,\n received,\n },\n ],\n `${field} must be of type ${expected}`\n );\n }\n}\n\n/**\n * Value out of range\n */\nexport class RangeValidationError extends ValidationError {\n constructor(field: string, min?: number, max?: number) {\n const parts: string[] = [];\n if (min !== undefined) parts.push(`at least ${min}`);\n if (max !== undefined) parts.push(`at most ${max}`);\n const message = `${field} must be ${parts.join(' and ')}`;\n\n super([{ path: field, message, rule: 'range', expected: { min, max } }], message);\n }\n}\n\n/**\n * String length violation\n */\nexport class LengthError extends ValidationError {\n constructor(field: string, min?: number, max?: number) {\n const parts: string[] = [];\n if (min !== undefined) parts.push(`at least ${min} characters`);\n if (max !== undefined) parts.push(`at most ${max} characters`);\n const message = `${field} must be ${parts.join(' and ')}`;\n\n super([{ path: field, message, rule: 'length', expected: { min, max } }], message);\n }\n}\n\n/**\n * Pattern mismatch\n */\nexport class PatternError extends ValidationError {\n constructor(field: string, pattern: string, message?: string) {\n super(\n [\n {\n path: field,\n message: message ?? `${field} does not match required pattern`,\n rule: 'pattern',\n expected: pattern,\n },\n ],\n message ?? `${field} does not match required pattern`\n );\n }\n}\n\n/**\n * Invalid email format\n */\nexport class InvalidEmailError extends ValidationError {\n constructor(field = 'email') {\n super(\n [{ path: field, message: 'Invalid email address', rule: 'email' }],\n 'Invalid email address'\n );\n }\n}\n\n/**\n * Invalid URL format\n */\nexport class InvalidUrlError extends ValidationError {\n constructor(field = 'url') {\n super([{ path: field, message: 'Invalid URL', rule: 'url' }], 'Invalid URL');\n }\n}\n","/**\n * @nextrush/errors - Error Factory\n *\n * Factory functions for creating errors.\n *\n * @packageDocumentation\n */\n\nimport { HttpError, NextRushError } from './base';\nimport {\n BadGatewayError,\n BadRequestError,\n ConflictError,\n ForbiddenError,\n GatewayTimeoutError,\n InternalServerError,\n MethodNotAllowedError,\n NotFoundError,\n NotImplementedError,\n ServiceUnavailableError,\n TooManyRequestsError,\n UnauthorizedError,\n UnprocessableEntityError,\n type HttpErrorOptions,\n} from './http-errors';\n\n/**\n * HTTP status code to error class mapping\n */\nconst ERROR_MAP: Record<number, new (message?: string, options?: HttpErrorOptions) => HttpError> = {\n 400: BadRequestError,\n 401: UnauthorizedError,\n 403: ForbiddenError,\n 404: NotFoundError,\n 409: ConflictError,\n 422: UnprocessableEntityError,\n 429: TooManyRequestsError,\n 500: InternalServerError,\n 501: NotImplementedError,\n 502: BadGatewayError,\n 503: ServiceUnavailableError,\n 504: GatewayTimeoutError,\n};\n\n/**\n * Create an HTTP error by status code\n */\nexport function createError(\n status: number,\n message?: string,\n options?: HttpErrorOptions\n): HttpError {\n // Special case: MethodNotAllowedError requires allowedMethods array\n if (status === 405) {\n return new MethodNotAllowedError([], message, options);\n }\n\n const ErrorClass = ERROR_MAP[status];\n\n if (ErrorClass) {\n return new ErrorClass(message, options);\n }\n\n // Fallback: let HttpError constructor resolve the message via getHttpStatusMessage()\n return new HttpError(status, message, options);\n}\n\n/**\n * Create a 400 Bad Request error\n */\nexport function badRequest(message?: string, options?: HttpErrorOptions): BadRequestError {\n return new BadRequestError(message, options);\n}\n\n/**\n * Create a 401 Unauthorized error\n */\nexport function unauthorized(message?: string, options?: HttpErrorOptions): UnauthorizedError {\n return new UnauthorizedError(message, options);\n}\n\n/**\n * Create a 403 Forbidden error\n */\nexport function forbidden(message?: string, options?: HttpErrorOptions): ForbiddenError {\n return new ForbiddenError(message, options);\n}\n\n/**\n * Create a 404 Not Found error\n */\nexport function notFound(message?: string, options?: HttpErrorOptions): NotFoundError {\n return new NotFoundError(message, options);\n}\n\n/**\n * Create a 405 Method Not Allowed error\n */\nexport function methodNotAllowed(\n allowedMethods?: string[],\n message?: string,\n options?: HttpErrorOptions\n): MethodNotAllowedError {\n return new MethodNotAllowedError(allowedMethods, message, options);\n}\n\n/**\n * Create a 409 Conflict error\n */\nexport function conflict(message?: string, options?: HttpErrorOptions): ConflictError {\n return new ConflictError(message, options);\n}\n\n/**\n * Create a 422 Unprocessable Entity error\n */\nexport function unprocessableEntity(\n message?: string,\n options?: HttpErrorOptions\n): UnprocessableEntityError {\n return new UnprocessableEntityError(message, options);\n}\n\n/**\n * Create a 429 Too Many Requests error\n */\nexport function tooManyRequests(\n message?: string,\n options?: HttpErrorOptions & { retryAfter?: number }\n): TooManyRequestsError {\n return new TooManyRequestsError(message, options);\n}\n\n/**\n * Create a 500 Internal Server Error\n */\nexport function internalError(message?: string, options?: HttpErrorOptions): InternalServerError {\n return new InternalServerError(message, options);\n}\n\n/**\n * Create a 502 Bad Gateway error\n */\nexport function badGateway(message?: string, options?: HttpErrorOptions): BadGatewayError {\n return new BadGatewayError(message, options);\n}\n\n/**\n * Create a 503 Service Unavailable error\n */\nexport function serviceUnavailable(\n message?: string,\n options?: HttpErrorOptions & { retryAfter?: number }\n): ServiceUnavailableError {\n return new ServiceUnavailableError(message, options);\n}\n\n/**\n * Create a 504 Gateway Timeout error\n */\nexport function gatewayTimeout(message?: string, options?: HttpErrorOptions): GatewayTimeoutError {\n return new GatewayTimeoutError(message, options);\n}\n\n/**\n * Check if an error is a NextRush HttpError\n */\nexport function isHttpError(error: unknown): error is HttpError {\n return error instanceof HttpError;\n}\n\n/**\n * Get HTTP status from any error\n *\n * Checks NextRushError first (covers HttpError, ValidationError, and all subclasses),\n * then falls back to duck-typed status property.\n */\nexport function getErrorStatus(error: unknown): number {\n if (error instanceof NextRushError) {\n return error.status;\n }\n if (\n error != null &&\n typeof error === 'object' &&\n 'status' in error &&\n typeof (error as { status: unknown }).status === 'number'\n ) {\n const status = (error as { status: number }).status;\n return status >= 400 && status < 600 ? status : 500;\n }\n return 500;\n}\n\n/**\n * Get error message safe for client response\n *\n * Exposes message for any NextRushError (including ValidationError)\n * when the error's expose flag is true.\n */\nexport function getSafeErrorMessage(error: unknown): string {\n if (error instanceof NextRushError && error.expose) {\n return error.message;\n }\n return 'Internal Server Error';\n}\n","/**\n * @nextrush/errors - Error Handler Middleware\n *\n * Middleware for handling errors in NextRush applications.\n *\n * @packageDocumentation\n */\n\nimport type { Context, Middleware, Next } from '@nextrush/types';\nimport { HttpError, NextRushError, getHttpStatusMessage } from './base';\n\n/**\n * Minimal context interface for error handling.\n *\n * @deprecated Use `Context` from `@nextrush/types` instead.\n * Kept for backward compatibility — will be removed in v4.\n */\nexport interface ErrorContext {\n method: string;\n path: string;\n status: number;\n json: (data: unknown) => void;\n}\n\n/**\n * Error handler middleware function type.\n *\n * @deprecated Use `Middleware` from `@nextrush/types` instead.\n * Kept for backward compatibility — will be removed in v4.\n */\nexport type ErrorMiddleware = Middleware;\n\n/**\n * Error handler options\n */\nexport interface ErrorHandlerOptions {\n /** Include stack trace in development */\n includeStack?: boolean;\n\n /** Custom error logger */\n logger?: (error: Error, ctx: Context) => void;\n\n /** Custom error transformer */\n transform?: (error: Error, ctx: Context) => Record<string, unknown>;\n\n /** Handle specific error types */\n handlers?: Map<new (...args: unknown[]) => Error, (error: Error, ctx: Context) => void>;\n}\n\n/**\n * Default error logger\n */\nfunction defaultLogger(error: Error, ctx: Context): void {\n const status = error instanceof HttpError ? error.status : 500;\n\n if (status >= 500) {\n console.error(`[ERROR] ${ctx.method} ${ctx.path}:`, error);\n } else {\n console.warn(`[WARN] ${ctx.method} ${ctx.path}: ${error.message}`);\n }\n}\n\n/**\n * Create error handler middleware\n *\n * @example\n * ```typescript\n * const app = createApp();\n *\n * // Add error handler first\n * app.use(errorHandler({\n * includeStack: process.env.NODE_ENV !== 'production',\n * logger: (err, ctx) => myLogger.error(err),\n * }));\n * ```\n */\nexport function errorHandler(options: ErrorHandlerOptions = {}): Middleware {\n const { includeStack = false, logger = defaultLogger, transform, handlers } = options;\n\n return async (ctx: Context, next: Next): Promise<void> => {\n try {\n await next();\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n\n // Log the error\n logger(err, ctx);\n\n // Check for custom handlers\n if (handlers) {\n for (const [ErrorType, handler] of handlers) {\n if (err instanceof ErrorType) {\n handler(err, ctx);\n return;\n }\n }\n }\n\n // Determine status code\n let status = 500;\n let expose = false;\n let code = 'INTERNAL_ERROR';\n let details: Record<string, unknown> | undefined;\n\n if (err instanceof HttpError || err instanceof NextRushError) {\n status = err.status;\n expose = err.expose;\n code = err.code;\n details = err.details;\n }\n\n ctx.status = status;\n\n // Build response body\n let body: Record<string, unknown>;\n\n if (transform) {\n body = transform(err, ctx);\n } else {\n body = {\n error: expose ? err.name : getHttpStatusMessage(status),\n message: expose ? err.message : 'Internal Server Error',\n code,\n status,\n };\n\n if (expose && details) {\n body.details = details;\n }\n\n if (includeStack && err.stack) {\n body.stack = err.stack.split('\\n').map((line) => line.trim());\n }\n }\n\n ctx.json(body);\n }\n };\n}\n\n/**\n * Not found handler middleware - catches unhandled requests\n *\n * @example\n * ```typescript\n * // Add at the end of middleware chain\n * app.use(notFoundHandler());\n * ```\n */\nexport function notFoundHandler(message = 'Not Found'): Middleware {\n return async (ctx: Context, next: Next): Promise<void> => {\n await next();\n // Only handle if no response was sent and status indicates unhandled\n if (!ctx.responded && ctx.status === 404) {\n ctx.json({\n error: 'NotFoundError',\n message,\n code: 'NOT_FOUND',\n status: 404,\n });\n }\n };\n}\n\n/**\n * Catch async errors wrapper for route handlers\n *\n * @example\n * ```typescript\n * router.get('/users/:id', catchAsync(async (ctx) => {\n * const user = await db.users.findById(ctx.params.id);\n * if (!user) throw new NotFoundError('User not found');\n * ctx.json(user);\n * }));\n * ```\n *\n * @deprecated This wrapper is redundant — async errors propagate naturally\n * through the middleware chain and are caught by `errorHandler()`. Use the\n * handler directly instead.\n */\nexport function catchAsync(handler: (ctx: Context, next: Next) => Promise<void>): Middleware {\n return handler;\n}\n"],"mappings":"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","names":["V8Error","Error","NextRushError","status","code","expose","details","cause","message","options","name","captureStackTrace","toJSON","json","error","toResponse","body","HTTP_STATUS_MESSAGES","getHttpStatusMessage","HttpError","BadRequestError","HttpError","message","options","code","UnauthorizedError","PaymentRequiredError","ForbiddenError","NotFoundError","MethodNotAllowedError","allowedMethods","details","NotAcceptableError","ProxyAuthRequiredError","RequestTimeoutError","ConflictError","GoneError","LengthRequiredError","PreconditionFailedError","PayloadTooLargeError","UriTooLongError","UnsupportedMediaTypeError","RangeNotSatisfiableError","ExpectationFailedError","ImATeapotError","UnprocessableEntityError","LockedError","FailedDependencyError","TooEarlyError","UpgradeRequiredError","PreconditionRequiredError","TooManyRequestsError","retryAfter","undefined","RequestHeaderFieldsTooLargeError","UnavailableForLegalReasonsError","InternalServerError","expose","NotImplementedError","BadGatewayError","ServiceUnavailableError","GatewayTimeoutError","HttpVersionNotSupportedError","VariantAlsoNegotiatesError","InsufficientStorageError","LoopDetectedError","NotExtendedError","NetworkAuthRequiredError","ValidationError","NextRushError","issues","message","status","code","expose","fromField","path","rule","fromFields","errors","Object","entries","map","hasErrorFor","some","issue","getErrorsFor","filter","getFirstError","find","toFlatObject","result","toJSON","error","name","expected","undefined","RequiredFieldError","field","TypeMismatchError","received","RangeValidationError","min","max","parts","push","join","LengthError","PatternError","pattern","InvalidEmailError","InvalidUrlError","ERROR_MAP","BadRequestError","UnauthorizedError","ForbiddenError","NotFoundError","ConflictError","UnprocessableEntityError","TooManyRequestsError","InternalServerError","NotImplementedError","BadGatewayError","ServiceUnavailableError","GatewayTimeoutError","createError","status","message","options","MethodNotAllowedError","ErrorClass","HttpError","badRequest","unauthorized","forbidden","notFound","methodNotAllowed","allowedMethods","conflict","unprocessableEntity","tooManyRequests","internalError","badGateway","serviceUnavailable","gatewayTimeout","isHttpError","error","getErrorStatus","NextRushError","getSafeErrorMessage","expose","defaultLogger","error","ctx","status","HttpError","console","method","path","warn","message","errorHandler","options","includeStack","logger","transform","handlers","next","err","Error","String","ErrorType","handler","expose","code","details","NextRushError","body","name","getHttpStatusMessage","stack","split","map","line","trim","json","notFoundHandler","responded","catchAsync"]}
1
+ {"version":3,"sources":["../src/codes.ts","../src/base.ts","../src/http-errors.ts","../src/validation.ts","../src/factory.ts","../src/middleware.ts"],"sourcesContent":["/**\n * @nextrush/errors - Central Error Code Registry\n *\n * Single source of truth mapping HTTP status codes to their canonical,\n * machine-readable error codes (audit E-4). Both the typed error classes and\n * the {@link createError} factory resolve codes through this registry, so a\n * given status maps to exactly one code regardless of construction path.\n *\n * @packageDocumentation\n */\n\n/**\n * Canonical error code for each supported HTTP status.\n *\n * @remarks\n * Keep this in sync with the typed classes in `http-errors.ts`. The\n * `audit-fixes` test suite asserts `createError(status).code === ERROR_CODES[status]`\n * for every entry, so drift between a class and this registry fails CI.\n */\nexport const ERROR_CODES: Readonly<Record<number, string>> = Object.freeze({\n 400: 'BAD_REQUEST',\n 401: 'UNAUTHORIZED',\n 402: 'PAYMENT_REQUIRED',\n 403: 'FORBIDDEN',\n 404: 'NOT_FOUND',\n 405: 'METHOD_NOT_ALLOWED',\n 406: 'NOT_ACCEPTABLE',\n 407: 'PROXY_AUTH_REQUIRED',\n 408: 'REQUEST_TIMEOUT',\n 409: 'CONFLICT',\n 410: 'GONE',\n 411: 'LENGTH_REQUIRED',\n 412: 'PRECONDITION_FAILED',\n 413: 'PAYLOAD_TOO_LARGE',\n 414: 'URI_TOO_LONG',\n 415: 'UNSUPPORTED_MEDIA_TYPE',\n 416: 'RANGE_NOT_SATISFIABLE',\n 417: 'EXPECTATION_FAILED',\n 418: 'IM_A_TEAPOT',\n 422: 'UNPROCESSABLE_ENTITY',\n 423: 'LOCKED',\n 424: 'FAILED_DEPENDENCY',\n 425: 'TOO_EARLY',\n 426: 'UPGRADE_REQUIRED',\n 428: 'PRECONDITION_REQUIRED',\n 429: 'TOO_MANY_REQUESTS',\n 431: 'REQUEST_HEADER_FIELDS_TOO_LARGE',\n 451: 'UNAVAILABLE_FOR_LEGAL_REASONS',\n 500: 'INTERNAL_SERVER_ERROR',\n 501: 'NOT_IMPLEMENTED',\n 502: 'BAD_GATEWAY',\n 503: 'SERVICE_UNAVAILABLE',\n 504: 'GATEWAY_TIMEOUT',\n 505: 'HTTP_VERSION_NOT_SUPPORTED',\n 506: 'VARIANT_ALSO_NEGOTIATES',\n 507: 'INSUFFICIENT_STORAGE',\n 508: 'LOOP_DETECTED',\n 510: 'NOT_EXTENDED',\n 511: 'NETWORK_AUTH_REQUIRED',\n});\n\n/**\n * Resolve the canonical error code for an HTTP status.\n *\n * @param status - HTTP status code.\n * @returns The registered canonical code, or `HTTP_<status>` for statuses with\n * no dedicated class.\n */\nexport function codeForStatus(status: number): string {\n return ERROR_CODES[status] ?? `HTTP_${status}`;\n}\n\n/** Generic internal-error code used when no status-specific code applies. */\nexport const GENERIC_ERROR_CODE = 'INTERNAL_ERROR';\n\n/** Canonical code for validation failures. */\nexport const VALIDATION_ERROR_CODE = 'VALIDATION_ERROR';\n","/**\n * @nextrush/errors - Base Error Classes\n *\n * Foundational error classes for NextRush framework.\n *\n * @packageDocumentation\n */\n\nimport { codeForStatus } from './codes';\n\n/** Options accepted by {@link NextRushError.hydrate} when reconstructing errors. */\ninterface HydrateOptions {\n status?: number;\n code?: string;\n details?: Record<string, unknown>;\n requestId?: string;\n traceId?: string;\n timestamp?: string;\n}\n\nconst V8Error = Error as ErrorConstructor & {\n captureStackTrace?: (targetObject: object, constructorOpt?: Function) => void;\n};\n\n/** Maximum depth walked when serializing a `cause` chain (audit E-2). */\nconst MAX_CAUSE_DEPTH = 5;\n\n/**\n * Serialize an error `cause` chain into a plain, JSON-safe object.\n *\n * @remarks\n * Walks nested `cause` links up to {@link MAX_CAUSE_DEPTH}, guards against\n * cyclic chains via a visited set, and only surfaces `name`/`message`/`code`\n * so no unexpected enumerable properties (or secrets on ad-hoc error objects)\n * leak. Returns `undefined` when there is nothing meaningful to serialize.\n */\nfunction serializeCause(cause: unknown, seen: Set<unknown>, depth: number): unknown {\n if (cause === undefined || cause === null || depth >= MAX_CAUSE_DEPTH) return undefined;\n if (typeof cause !== 'object') return { message: String(cause) };\n if (seen.has(cause)) return undefined; // cycle guard\n seen.add(cause);\n\n const err = cause as { name?: unknown; message?: unknown; code?: unknown; cause?: unknown };\n const out: Record<string, unknown> = {};\n if (typeof err.name === 'string') out.name = err.name;\n if (typeof err.message === 'string') out.message = err.message;\n if (typeof err.code === 'string') out.code = err.code;\n\n const nested = serializeCause(err.cause, seen, depth + 1);\n if (nested !== undefined) out.cause = nested;\n\n return out;\n}\n\n/**\n * Base error class for all NextRush errors\n */\nexport class NextRushError extends Error {\n /** HTTP status code */\n readonly status: number;\n\n /** Error code for programmatic handling */\n readonly code: string;\n\n /** Whether error message is safe to expose to client */\n readonly expose: boolean;\n\n /** Additional error details */\n readonly details?: Record<string, unknown>;\n\n /** Original error that caused this error */\n readonly cause?: unknown;\n\n /** Correlation/request identifier for tracing across boundaries (audit E-5). */\n readonly requestId?: string;\n\n /** Distributed-trace identifier (audit E-5). */\n readonly traceId?: string;\n\n /** ISO-8601 timestamp of when the error was created, when supplied. */\n readonly timestamp?: string;\n\n constructor(\n message: string,\n options: {\n status?: number;\n code?: string;\n expose?: boolean;\n details?: Record<string, unknown>;\n cause?: unknown;\n requestId?: string;\n traceId?: string;\n timestamp?: string;\n } = {}\n ) {\n // Pass cause to the native Error constructor so `util.inspect` / logging\n // tooling walks the chain natively, in addition to our own `cause` field.\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = this.constructor.name;\n this.status = options.status ?? 500;\n this.code = options.code ?? 'INTERNAL_ERROR';\n this.expose = options.expose ?? this.status < 500;\n // Freeze a shallow snapshot so the error owns immutable details and the\n // caller's object cannot be mutated through the error (audit E-6).\n this.details = options.details ? Object.freeze({ ...options.details }) : undefined;\n this.cause = options.cause;\n this.requestId = options.requestId;\n this.traceId = options.traceId;\n this.timestamp = options.timestamp;\n\n // Maintain proper stack trace for V8\n // Skip for common client errors (4xx with expose=true) to reduce overhead.\n // These are expected control-flow errors, not bugs — stack traces add cost\n // without diagnostic value in production.\n if (V8Error.captureStackTrace && !(this.expose && this.status < 500)) {\n V8Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Convert error to JSON representation\n */\n toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {\n error: this.name,\n message: this.expose ? this.message : 'Internal Server Error',\n code: this.code,\n status: this.status,\n };\n\n if (this.expose && this.details) {\n json.details = this.details;\n }\n\n // Surface the cause chain for diagnosability, but only on exposed errors —\n // a non-exposed 5xx cause may contain internal detail (audit E-2). Server\n // -side logging should read `error.cause` directly, which is never gated.\n if (this.expose && this.cause !== undefined) {\n const serialized = serializeCause(this.cause, new Set(), 0);\n if (serialized !== undefined) {\n json.cause = serialized;\n }\n }\n\n // Correlation identifiers are safe to surface and are the primary handle\n // for cross-service debugging (audit E-5). Only emitted when set, so the\n // default serialized shape is unchanged.\n if (this.requestId !== undefined) json.requestId = this.requestId;\n if (this.traceId !== undefined) json.traceId = this.traceId;\n if (this.timestamp !== undefined) json.timestamp = this.timestamp;\n\n return json;\n }\n\n /**\n * Reconstruct a {@link NextRushError} from a serialized {@link toJSON} payload\n * (audit E-7).\n *\n * @remarks\n * Enables cross-service transport: a downstream service can rebuild a typed\n * error (with a working `instanceof NextRushError`) from the JSON it received,\n * rather than being left with an opaque plain object. `message` falls back to\n * a generic string when the source error was not exposed.\n *\n * @param json - A payload previously produced by {@link toJSON}.\n * @returns A reconstructed {@link NextRushError}.\n */\n static fromJSON(json: Record<string, unknown>): NextRushError {\n return NextRushError.hydrate(json, (message, options) => new NextRushError(message, options));\n }\n\n /**\n * Shared hydration logic for {@link fromJSON} across the hierarchy.\n * @internal\n */\n protected static hydrate<T extends NextRushError>(\n json: Record<string, unknown>,\n build: (message: string, options: HydrateOptions) => T\n ): T {\n const status = typeof json.status === 'number' ? json.status : 500;\n const message = typeof json.message === 'string' ? json.message : getHttpStatusMessage(status);\n return build(message, {\n status,\n code: typeof json.code === 'string' ? json.code : undefined,\n details:\n json.details !== null && typeof json.details === 'object'\n ? (json.details as Record<string, unknown>)\n : undefined,\n requestId: typeof json.requestId === 'string' ? json.requestId : undefined,\n traceId: typeof json.traceId === 'string' ? json.traceId : undefined,\n timestamp: typeof json.timestamp === 'string' ? json.timestamp : undefined,\n });\n }\n\n /**\n * Create a response-safe version of the error\n */\n toResponse(): { status: number; body: Record<string, unknown> } {\n return {\n status: this.status,\n body: this.toJSON(),\n };\n }\n}\n\n/**\n * Default HTTP status messages\n */\nconst HTTP_STATUS_MESSAGES: Record<number, string> = {\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 402: 'Payment Required',\n 403: 'Forbidden',\n 404: 'Not Found',\n 405: 'Method Not Allowed',\n 406: 'Not Acceptable',\n 407: 'Proxy Authentication Required',\n 408: 'Request Timeout',\n 409: 'Conflict',\n 410: 'Gone',\n 411: 'Length Required',\n 412: 'Precondition Failed',\n 413: 'Payload Too Large',\n 414: 'URI Too Long',\n 415: 'Unsupported Media Type',\n 416: 'Range Not Satisfiable',\n 417: 'Expectation Failed',\n 418: \"I'm a Teapot\",\n 422: 'Unprocessable Entity',\n 423: 'Locked',\n 424: 'Failed Dependency',\n 425: 'Too Early',\n 426: 'Upgrade Required',\n 428: 'Precondition Required',\n 429: 'Too Many Requests',\n 431: 'Request Header Fields Too Large',\n 451: 'Unavailable For Legal Reasons',\n 500: 'Internal Server Error',\n 501: 'Not Implemented',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n 505: 'HTTP Version Not Supported',\n 506: 'Variant Also Negotiates',\n 507: 'Insufficient Storage',\n 508: 'Loop Detected',\n 510: 'Not Extended',\n 511: 'Network Authentication Required',\n};\n\n/**\n * Get default message for an HTTP status code\n */\nexport function getHttpStatusMessage(status: number): string {\n return HTTP_STATUS_MESSAGES[status] ?? `HTTP Error ${status}`;\n}\n\n/**\n * Base class for HTTP errors\n */\nexport class HttpError extends NextRushError {\n constructor(\n status: number,\n message?: string,\n options: {\n code?: string;\n expose?: boolean;\n details?: Record<string, unknown>;\n cause?: unknown;\n requestId?: string;\n traceId?: string;\n timestamp?: string;\n } = {}\n ) {\n super(message ?? getHttpStatusMessage(status), {\n status,\n code: options.code ?? codeForStatus(status),\n expose: options.expose ?? status < 500,\n details: options.details,\n cause: options.cause,\n requestId: options.requestId,\n traceId: options.traceId,\n timestamp: options.timestamp,\n });\n }\n\n /**\n * Reconstruct an {@link HttpError} from a serialized {@link NextRushError.toJSON}\n * payload (audit E-7).\n *\n * @param json - A payload previously produced by `toJSON()`.\n * @returns A reconstructed {@link HttpError}.\n */\n static override fromJSON(json: Record<string, unknown>): HttpError {\n return NextRushError.hydrate(\n json,\n (message, options) =>\n new HttpError(options.status ?? 500, message, {\n code: options.code,\n details: options.details,\n requestId: options.requestId,\n traceId: options.traceId,\n timestamp: options.timestamp,\n })\n );\n }\n}\n","/**\n * @nextrush/errors - HTTP Error Classes\n *\n * Standard HTTP error classes for common status codes.\n *\n * @packageDocumentation\n */\n\nimport { HttpError } from './base';\n\n/**\n * Options for creating HTTP errors\n */\nexport interface HttpErrorOptions {\n code?: string;\n expose?: boolean;\n details?: Record<string, unknown>;\n cause?: unknown;\n /** Correlation/request identifier (audit E-5). */\n requestId?: string;\n /** Distributed-trace identifier (audit E-5). */\n traceId?: string;\n /** ISO-8601 creation timestamp (audit E-5). */\n timestamp?: string;\n}\n\n// =============================================================================\n// 4xx Client Errors\n// =============================================================================\n\n/**\n * 400 Bad Request - Invalid syntax or malformed request\n */\nexport class BadRequestError extends HttpError {\n constructor(message = 'Bad Request', options: HttpErrorOptions = {}) {\n super(400, message, { code: 'BAD_REQUEST', ...options });\n }\n}\n\n/**\n * 401 Unauthorized - Authentication required\n */\nexport class UnauthorizedError extends HttpError {\n constructor(message = 'Unauthorized', options: HttpErrorOptions = {}) {\n super(401, message, { code: 'UNAUTHORIZED', ...options });\n }\n}\n\n/**\n * 402 Payment Required - Payment needed\n */\nexport class PaymentRequiredError extends HttpError {\n constructor(message = 'Payment Required', options: HttpErrorOptions = {}) {\n super(402, message, { code: 'PAYMENT_REQUIRED', ...options });\n }\n}\n\n/**\n * 403 Forbidden - Access denied\n */\nexport class ForbiddenError extends HttpError {\n constructor(message = 'Forbidden', options: HttpErrorOptions = {}) {\n super(403, message, { code: 'FORBIDDEN', ...options });\n }\n}\n\n/**\n * 404 Not Found - Resource not found\n */\nexport class NotFoundError extends HttpError {\n constructor(message = 'Not Found', options: HttpErrorOptions = {}) {\n super(404, message, { code: 'NOT_FOUND', ...options });\n }\n}\n\n/**\n * 405 Method Not Allowed - HTTP method not supported\n */\nexport class MethodNotAllowedError extends HttpError {\n readonly allowedMethods: string[];\n\n constructor(\n allowedMethods: string[] = [],\n message = 'Method Not Allowed',\n options: HttpErrorOptions = {}\n ) {\n super(405, message, {\n code: 'METHOD_NOT_ALLOWED',\n details: { allowedMethods },\n ...options,\n });\n this.allowedMethods = allowedMethods;\n }\n}\n\n/**\n * 406 Not Acceptable - Cannot produce acceptable response\n */\nexport class NotAcceptableError extends HttpError {\n constructor(message = 'Not Acceptable', options: HttpErrorOptions = {}) {\n super(406, message, { code: 'NOT_ACCEPTABLE', ...options });\n }\n}\n\n/**\n * 407 Proxy Authentication Required\n */\nexport class ProxyAuthRequiredError extends HttpError {\n constructor(message = 'Proxy Authentication Required', options: HttpErrorOptions = {}) {\n super(407, message, { code: 'PROXY_AUTH_REQUIRED', ...options });\n }\n}\n\n/**\n * 408 Request Timeout - Client took too long\n */\nexport class RequestTimeoutError extends HttpError {\n constructor(message = 'Request Timeout', options: HttpErrorOptions = {}) {\n super(408, message, { code: 'REQUEST_TIMEOUT', ...options });\n }\n}\n\n/**\n * 409 Conflict - Request conflicts with current state\n */\nexport class ConflictError extends HttpError {\n constructor(message = 'Conflict', options: HttpErrorOptions = {}) {\n super(409, message, { code: 'CONFLICT', ...options });\n }\n}\n\n/**\n * 410 Gone - Resource permanently deleted\n */\nexport class GoneError extends HttpError {\n constructor(message = 'Gone', options: HttpErrorOptions = {}) {\n super(410, message, { code: 'GONE', ...options });\n }\n}\n\n/**\n * 411 Length Required - Content-Length header required\n */\nexport class LengthRequiredError extends HttpError {\n constructor(message = 'Length Required', options: HttpErrorOptions = {}) {\n super(411, message, { code: 'LENGTH_REQUIRED', ...options });\n }\n}\n\n/**\n * 412 Precondition Failed - Precondition in headers not met\n */\nexport class PreconditionFailedError extends HttpError {\n constructor(message = 'Precondition Failed', options: HttpErrorOptions = {}) {\n super(412, message, { code: 'PRECONDITION_FAILED', ...options });\n }\n}\n\n/**\n * 413 Payload Too Large - Request body too large\n */\nexport class PayloadTooLargeError extends HttpError {\n constructor(message = 'Payload Too Large', options: HttpErrorOptions = {}) {\n super(413, message, { code: 'PAYLOAD_TOO_LARGE', ...options });\n }\n}\n\n/**\n * 414 URI Too Long - Request URI too long\n */\nexport class UriTooLongError extends HttpError {\n constructor(message = 'URI Too Long', options: HttpErrorOptions = {}) {\n super(414, message, { code: 'URI_TOO_LONG', ...options });\n }\n}\n\n/**\n * 415 Unsupported Media Type - Content type not supported\n */\nexport class UnsupportedMediaTypeError extends HttpError {\n constructor(message = 'Unsupported Media Type', options: HttpErrorOptions = {}) {\n super(415, message, { code: 'UNSUPPORTED_MEDIA_TYPE', ...options });\n }\n}\n\n/**\n * 416 Range Not Satisfiable - Cannot satisfy Range header\n */\nexport class RangeNotSatisfiableError extends HttpError {\n constructor(message = 'Range Not Satisfiable', options: HttpErrorOptions = {}) {\n super(416, message, { code: 'RANGE_NOT_SATISFIABLE', ...options });\n }\n}\n\n/**\n * 417 Expectation Failed - Cannot meet Expect header\n */\nexport class ExpectationFailedError extends HttpError {\n constructor(message = 'Expectation Failed', options: HttpErrorOptions = {}) {\n super(417, message, { code: 'EXPECTATION_FAILED', ...options });\n }\n}\n\n/**\n * 418 I'm a Teapot - RFC 2324\n */\nexport class ImATeapotError extends HttpError {\n constructor(message = \"I'm a teapot\", options: HttpErrorOptions = {}) {\n super(418, message, { code: 'IM_A_TEAPOT', ...options });\n }\n}\n\n/**\n * 422 Unprocessable Entity - Semantic errors\n */\nexport class UnprocessableEntityError extends HttpError {\n constructor(message = 'Unprocessable Entity', options: HttpErrorOptions = {}) {\n super(422, message, { code: 'UNPROCESSABLE_ENTITY', ...options });\n }\n}\n\n/**\n * 423 Locked - Resource is locked\n */\nexport class LockedError extends HttpError {\n constructor(message = 'Locked', options: HttpErrorOptions = {}) {\n super(423, message, { code: 'LOCKED', ...options });\n }\n}\n\n/**\n * 424 Failed Dependency - Dependent request failed\n */\nexport class FailedDependencyError extends HttpError {\n constructor(message = 'Failed Dependency', options: HttpErrorOptions = {}) {\n super(424, message, { code: 'FAILED_DEPENDENCY', ...options });\n }\n}\n\n/**\n * 425 Too Early - Request replayed too early\n */\nexport class TooEarlyError extends HttpError {\n constructor(message = 'Too Early', options: HttpErrorOptions = {}) {\n super(425, message, { code: 'TOO_EARLY', ...options });\n }\n}\n\n/**\n * 426 Upgrade Required - Client should upgrade protocol\n */\nexport class UpgradeRequiredError extends HttpError {\n constructor(message = 'Upgrade Required', options: HttpErrorOptions = {}) {\n super(426, message, { code: 'UPGRADE_REQUIRED', ...options });\n }\n}\n\n/**\n * 428 Precondition Required - Origin server requires conditional request\n */\nexport class PreconditionRequiredError extends HttpError {\n constructor(message = 'Precondition Required', options: HttpErrorOptions = {}) {\n super(428, message, { code: 'PRECONDITION_REQUIRED', ...options });\n }\n}\n\n/**\n * 429 Too Many Requests - Rate limit exceeded\n */\nexport class TooManyRequestsError extends HttpError {\n readonly retryAfter?: number;\n\n constructor(\n message = 'Too Many Requests',\n options: HttpErrorOptions & { retryAfter?: number } = {}\n ) {\n super(429, message, {\n code: 'TOO_MANY_REQUESTS',\n details: options.retryAfter ? { retryAfter: options.retryAfter } : undefined,\n ...options,\n });\n this.retryAfter = options.retryAfter;\n }\n}\n\n/**\n * 431 Request Header Fields Too Large\n */\nexport class RequestHeaderFieldsTooLargeError extends HttpError {\n constructor(message = 'Request Header Fields Too Large', options: HttpErrorOptions = {}) {\n super(431, message, { code: 'REQUEST_HEADER_FIELDS_TOO_LARGE', ...options });\n }\n}\n\n/**\n * 451 Unavailable For Legal Reasons\n */\nexport class UnavailableForLegalReasonsError extends HttpError {\n constructor(message = 'Unavailable For Legal Reasons', options: HttpErrorOptions = {}) {\n super(451, message, { code: 'UNAVAILABLE_FOR_LEGAL_REASONS', ...options });\n }\n}\n\n// =============================================================================\n// 5xx Server Errors\n// =============================================================================\n\n/**\n * 500 Internal Server Error - Generic server error\n */\nexport class InternalServerError extends HttpError {\n constructor(message = 'Internal Server Error', options: HttpErrorOptions = {}) {\n super(500, message, { code: 'INTERNAL_SERVER_ERROR', expose: false, ...options });\n }\n}\n\n/**\n * 501 Not Implemented - Feature not implemented\n */\nexport class NotImplementedError extends HttpError {\n constructor(message = 'Not Implemented', options: HttpErrorOptions = {}) {\n super(501, message, { code: 'NOT_IMPLEMENTED', expose: false, ...options });\n }\n}\n\n/**\n * 502 Bad Gateway - Invalid upstream response\n */\nexport class BadGatewayError extends HttpError {\n constructor(message = 'Bad Gateway', options: HttpErrorOptions = {}) {\n super(502, message, { code: 'BAD_GATEWAY', expose: false, ...options });\n }\n}\n\n/**\n * 503 Service Unavailable - Server temporarily unavailable\n */\nexport class ServiceUnavailableError extends HttpError {\n readonly retryAfter?: number;\n\n constructor(\n message = 'Service Unavailable',\n options: HttpErrorOptions & { retryAfter?: number } = {}\n ) {\n super(503, message, {\n code: 'SERVICE_UNAVAILABLE',\n expose: false,\n ...options,\n });\n this.retryAfter = options.retryAfter;\n }\n}\n\n/**\n * 504 Gateway Timeout - Upstream timeout\n */\nexport class GatewayTimeoutError extends HttpError {\n constructor(message = 'Gateway Timeout', options: HttpErrorOptions = {}) {\n super(504, message, { code: 'GATEWAY_TIMEOUT', expose: false, ...options });\n }\n}\n\n/**\n * 505 HTTP Version Not Supported\n */\nexport class HttpVersionNotSupportedError extends HttpError {\n constructor(message = 'HTTP Version Not Supported', options: HttpErrorOptions = {}) {\n super(505, message, { code: 'HTTP_VERSION_NOT_SUPPORTED', expose: false, ...options });\n }\n}\n\n/**\n * 506 Variant Also Negotiates\n */\nexport class VariantAlsoNegotiatesError extends HttpError {\n constructor(message = 'Variant Also Negotiates', options: HttpErrorOptions = {}) {\n super(506, message, { code: 'VARIANT_ALSO_NEGOTIATES', expose: false, ...options });\n }\n}\n\n/**\n * 507 Insufficient Storage\n */\nexport class InsufficientStorageError extends HttpError {\n constructor(message = 'Insufficient Storage', options: HttpErrorOptions = {}) {\n super(507, message, { code: 'INSUFFICIENT_STORAGE', expose: false, ...options });\n }\n}\n\n/**\n * 508 Loop Detected\n */\nexport class LoopDetectedError extends HttpError {\n constructor(message = 'Loop Detected', options: HttpErrorOptions = {}) {\n super(508, message, { code: 'LOOP_DETECTED', expose: false, ...options });\n }\n}\n\n/**\n * 510 Not Extended\n */\nexport class NotExtendedError extends HttpError {\n constructor(message = 'Not Extended', options: HttpErrorOptions = {}) {\n super(510, message, { code: 'NOT_EXTENDED', expose: false, ...options });\n }\n}\n\n/**\n * 511 Network Authentication Required\n */\nexport class NetworkAuthRequiredError extends HttpError {\n constructor(message = 'Network Authentication Required', options: HttpErrorOptions = {}) {\n super(511, message, { code: 'NETWORK_AUTH_REQUIRED', expose: false, ...options });\n }\n}\n","/**\n * @nextrush/errors - Validation Error Classes\n *\n * Specialized errors for input validation.\n *\n * @packageDocumentation\n */\n\nimport { NextRushError } from './base';\n\n/**\n * Single validation issue\n */\nexport interface ValidationIssue {\n /** Field path (e.g., 'user.email' or 'items[0].name') */\n path: string;\n /** Error message for this field */\n message: string;\n /** Validation rule that failed */\n rule?: string;\n /** Expected value or constraint */\n expected?: unknown;\n /** Actual value received */\n received?: unknown;\n}\n\n/**\n * Validation error with multiple issues\n */\nexport class ValidationError extends NextRushError {\n /** List of validation issues */\n readonly issues: ValidationIssue[];\n\n constructor(issues: ValidationIssue[], message = 'Validation failed') {\n super(message, {\n status: 400,\n code: 'VALIDATION_ERROR',\n expose: true,\n });\n // Freeze a snapshot so issues are immutable after construction (audit E-6).\n this.issues = Object.freeze([...issues]) as ValidationIssue[];\n }\n\n /**\n * Create from a single field error\n */\n static fromField(path: string, message: string, rule?: string): ValidationError {\n return new ValidationError([{ path, message, rule }]);\n }\n\n /**\n * Create from multiple field errors\n */\n static fromFields(errors: Record<string, string>): ValidationError {\n const issues = Object.entries(errors).map(([path, message]) => ({\n path,\n message,\n }));\n return new ValidationError(issues);\n }\n\n /**\n * Check if a specific field has errors\n */\n hasErrorFor(path: string): boolean {\n return this.issues.some((issue) => issue.path === path);\n }\n\n /**\n * Get errors for a specific field\n */\n getErrorsFor(path: string): ValidationIssue[] {\n return this.issues.filter((issue) => issue.path === path);\n }\n\n /**\n * Get first error message for a field\n */\n getFirstError(path: string): string | undefined {\n return this.issues.find((issue) => issue.path === path)?.message;\n }\n\n /**\n * Convert to flat error object\n */\n toFlatObject(): Record<string, string> {\n const result: Record<string, string> = {};\n for (const issue of this.issues) {\n if (!result[issue.path]) {\n result[issue.path] = issue.message;\n }\n }\n return result;\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n error: this.name,\n message: this.message,\n code: this.code,\n status: this.status,\n // Strip `received` to prevent leaking sensitive input values (passwords, tokens)\n issues: this.issues.map(({ path, message, rule, expected }) => ({\n path,\n message,\n ...(rule !== undefined && { rule }),\n ...(expected !== undefined && { expected }),\n })),\n };\n }\n}\n\n/**\n * Required field missing\n */\nexport class RequiredFieldError extends ValidationError {\n constructor(field: string) {\n super(\n [{ path: field, message: `${field} is required`, rule: 'required' }],\n `${field} is required`\n );\n }\n}\n\n/**\n * Field type mismatch\n */\nexport class TypeMismatchError extends ValidationError {\n constructor(field: string, expected: string, received: string) {\n super(\n [\n {\n path: field,\n message: `Expected ${expected}, received ${received}`,\n rule: 'type',\n expected,\n received,\n },\n ],\n `${field} must be of type ${expected}`\n );\n }\n}\n\n/**\n * Value out of range\n */\nexport class RangeValidationError extends ValidationError {\n constructor(field: string, min?: number, max?: number) {\n const parts: string[] = [];\n if (min !== undefined) parts.push(`at least ${min}`);\n if (max !== undefined) parts.push(`at most ${max}`);\n const message = `${field} must be ${parts.join(' and ')}`;\n\n super([{ path: field, message, rule: 'range', expected: { min, max } }], message);\n }\n}\n\n/**\n * String length violation\n */\nexport class LengthError extends ValidationError {\n constructor(field: string, min?: number, max?: number) {\n const parts: string[] = [];\n if (min !== undefined) parts.push(`at least ${min} characters`);\n if (max !== undefined) parts.push(`at most ${max} characters`);\n const message = `${field} must be ${parts.join(' and ')}`;\n\n super([{ path: field, message, rule: 'length', expected: { min, max } }], message);\n }\n}\n\n/**\n * Pattern mismatch\n */\nexport class PatternError extends ValidationError {\n constructor(field: string, pattern: string, message?: string) {\n super(\n [\n {\n path: field,\n message: message ?? `${field} does not match required pattern`,\n rule: 'pattern',\n expected: pattern,\n },\n ],\n message ?? `${field} does not match required pattern`\n );\n }\n}\n\n/**\n * Invalid email format\n */\nexport class InvalidEmailError extends ValidationError {\n constructor(field = 'email') {\n super(\n [{ path: field, message: 'Invalid email address', rule: 'email' }],\n 'Invalid email address'\n );\n }\n}\n\n/**\n * Invalid URL format\n */\nexport class InvalidUrlError extends ValidationError {\n constructor(field = 'url') {\n super([{ path: field, message: 'Invalid URL', rule: 'url' }], 'Invalid URL');\n }\n}\n","/**\n * @nextrush/errors - Error Factory\n *\n * Factory functions for creating errors.\n *\n * @packageDocumentation\n */\n\nimport { HttpError, NextRushError } from './base';\nimport {\n BadGatewayError,\n BadRequestError,\n ConflictError,\n ExpectationFailedError,\n FailedDependencyError,\n ForbiddenError,\n GatewayTimeoutError,\n GoneError,\n HttpVersionNotSupportedError,\n ImATeapotError,\n InsufficientStorageError,\n InternalServerError,\n LengthRequiredError,\n LockedError,\n LoopDetectedError,\n MethodNotAllowedError,\n NetworkAuthRequiredError,\n NotAcceptableError,\n NotExtendedError,\n NotFoundError,\n NotImplementedError,\n PayloadTooLargeError,\n PaymentRequiredError,\n PreconditionFailedError,\n PreconditionRequiredError,\n ProxyAuthRequiredError,\n RangeNotSatisfiableError,\n RequestHeaderFieldsTooLargeError,\n RequestTimeoutError,\n ServiceUnavailableError,\n TooEarlyError,\n TooManyRequestsError,\n UnauthorizedError,\n UnavailableForLegalReasonsError,\n UnprocessableEntityError,\n UnsupportedMediaTypeError,\n UpgradeRequiredError,\n UriTooLongError,\n VariantAlsoNegotiatesError,\n type HttpErrorOptions,\n} from './http-errors';\n\n/**\n * HTTP status code to error class mapping.\n *\n * @remarks\n * Covers every status that has a dedicated typed class so {@link createError}\n * returns the correctly-coded instance (audit E-3). `405` is handled separately\n * because {@link MethodNotAllowedError} has a divergent constructor signature.\n */\nconst ERROR_MAP: Record<number, new (message?: string, options?: HttpErrorOptions) => HttpError> = {\n 400: BadRequestError,\n 401: UnauthorizedError,\n 402: PaymentRequiredError,\n 403: ForbiddenError,\n 404: NotFoundError,\n 406: NotAcceptableError,\n 407: ProxyAuthRequiredError,\n 408: RequestTimeoutError,\n 409: ConflictError,\n 410: GoneError,\n 411: LengthRequiredError,\n 412: PreconditionFailedError,\n 413: PayloadTooLargeError,\n 414: UriTooLongError,\n 415: UnsupportedMediaTypeError,\n 416: RangeNotSatisfiableError,\n 417: ExpectationFailedError,\n 418: ImATeapotError,\n 422: UnprocessableEntityError,\n 423: LockedError,\n 424: FailedDependencyError,\n 425: TooEarlyError,\n 426: UpgradeRequiredError,\n 428: PreconditionRequiredError,\n 429: TooManyRequestsError,\n 431: RequestHeaderFieldsTooLargeError,\n 451: UnavailableForLegalReasonsError,\n 500: InternalServerError,\n 501: NotImplementedError,\n 502: BadGatewayError,\n 503: ServiceUnavailableError,\n 504: GatewayTimeoutError,\n 505: HttpVersionNotSupportedError,\n 506: VariantAlsoNegotiatesError,\n 507: InsufficientStorageError,\n 508: LoopDetectedError,\n 510: NotExtendedError,\n 511: NetworkAuthRequiredError,\n};\n\n/**\n * Create an HTTP error by status code\n */\nexport function createError(\n status: number,\n message?: string,\n options?: HttpErrorOptions\n): HttpError {\n // Special case: MethodNotAllowedError requires allowedMethods array\n if (status === 405) {\n return new MethodNotAllowedError([], message, options);\n }\n\n const ErrorClass = ERROR_MAP[status];\n\n if (ErrorClass) {\n return new ErrorClass(message, options);\n }\n\n // Fallback: let HttpError constructor resolve the message via getHttpStatusMessage()\n return new HttpError(status, message, options);\n}\n\n/**\n * Create a 400 Bad Request error\n */\nexport function badRequest(message?: string, options?: HttpErrorOptions): BadRequestError {\n return new BadRequestError(message, options);\n}\n\n/**\n * Create a 401 Unauthorized error\n */\nexport function unauthorized(message?: string, options?: HttpErrorOptions): UnauthorizedError {\n return new UnauthorizedError(message, options);\n}\n\n/**\n * Create a 403 Forbidden error\n */\nexport function forbidden(message?: string, options?: HttpErrorOptions): ForbiddenError {\n return new ForbiddenError(message, options);\n}\n\n/**\n * Create a 404 Not Found error\n */\nexport function notFound(message?: string, options?: HttpErrorOptions): NotFoundError {\n return new NotFoundError(message, options);\n}\n\n/**\n * Create a 405 Method Not Allowed error\n */\nexport function methodNotAllowed(\n allowedMethods?: string[],\n message?: string,\n options?: HttpErrorOptions\n): MethodNotAllowedError {\n return new MethodNotAllowedError(allowedMethods, message, options);\n}\n\n/**\n * Create a 409 Conflict error\n */\nexport function conflict(message?: string, options?: HttpErrorOptions): ConflictError {\n return new ConflictError(message, options);\n}\n\n/**\n * Create a 422 Unprocessable Entity error\n */\nexport function unprocessableEntity(\n message?: string,\n options?: HttpErrorOptions\n): UnprocessableEntityError {\n return new UnprocessableEntityError(message, options);\n}\n\n/**\n * Create a 429 Too Many Requests error\n */\nexport function tooManyRequests(\n message?: string,\n options?: HttpErrorOptions & { retryAfter?: number }\n): TooManyRequestsError {\n return new TooManyRequestsError(message, options);\n}\n\n/**\n * Create a 500 Internal Server Error\n */\nexport function internalError(message?: string, options?: HttpErrorOptions): InternalServerError {\n return new InternalServerError(message, options);\n}\n\n/**\n * Create a 502 Bad Gateway error\n */\nexport function badGateway(message?: string, options?: HttpErrorOptions): BadGatewayError {\n return new BadGatewayError(message, options);\n}\n\n/**\n * Create a 503 Service Unavailable error\n */\nexport function serviceUnavailable(\n message?: string,\n options?: HttpErrorOptions & { retryAfter?: number }\n): ServiceUnavailableError {\n return new ServiceUnavailableError(message, options);\n}\n\n/**\n * Create a 504 Gateway Timeout error\n */\nexport function gatewayTimeout(message?: string, options?: HttpErrorOptions): GatewayTimeoutError {\n return new GatewayTimeoutError(message, options);\n}\n\n/**\n * Check if an error is a NextRush HttpError\n */\nexport function isHttpError(error: unknown): error is HttpError {\n return error instanceof HttpError;\n}\n\n/**\n * Get HTTP status from any error\n *\n * Checks NextRushError first (covers HttpError, ValidationError, and all subclasses),\n * then falls back to duck-typed status property.\n */\nexport function getErrorStatus(error: unknown): number {\n if (error instanceof NextRushError) {\n return error.status;\n }\n if (\n error != null &&\n typeof error === 'object' &&\n 'status' in error &&\n typeof (error as { status: unknown }).status === 'number'\n ) {\n const status = (error as { status: number }).status;\n return status >= 400 && status < 600 ? status : 500;\n }\n return 500;\n}\n\n/**\n * Get error message safe for client response\n *\n * Exposes message for any NextRushError (including ValidationError)\n * when the error's expose flag is true.\n */\nexport function getSafeErrorMessage(error: unknown): string {\n if (error instanceof NextRushError && error.expose) {\n return error.message;\n }\n return 'Internal Server Error';\n}\n","/**\n * @nextrush/errors - Error Handler Middleware\n *\n * Middleware for handling errors in NextRush applications.\n *\n * @packageDocumentation\n */\n\nimport type { Context, Middleware, Next } from '@nextrush/types';\nimport { HttpError, NextRushError, getHttpStatusMessage } from './base';\n\n/**\n * Error handler options\n */\nexport interface ErrorHandlerOptions {\n /** Include stack trace in development */\n includeStack?: boolean;\n\n /** Custom error logger */\n logger?: (error: Error, ctx: Context) => void;\n\n /** Custom error transformer */\n transform?: (error: Error, ctx: Context) => Record<string, unknown>;\n\n /** Handle specific error types */\n handlers?: Map<new (...args: unknown[]) => Error, (error: Error, ctx: Context) => void>;\n}\n\n/**\n * Default error logger\n */\nfunction defaultLogger(error: Error, ctx: Context): void {\n const status = error instanceof HttpError ? error.status : 500;\n\n if (status >= 500) {\n console.error(`[ERROR] ${ctx.method} ${ctx.path}:`, error);\n } else {\n console.warn(`[WARN] ${ctx.method} ${ctx.path}: ${error.message}`);\n }\n}\n\n/**\n * Create error handler middleware\n *\n * @example\n * ```typescript\n * const app = createApp();\n *\n * // Add error handler first\n * app.use(errorHandler({\n * includeStack: process.env.NODE_ENV !== 'production',\n * logger: (err, ctx) => myLogger.error(err),\n * }));\n * ```\n */\nexport function errorHandler(options: ErrorHandlerOptions = {}): Middleware {\n const { includeStack = false, logger = defaultLogger, transform, handlers } = options;\n\n return async (ctx: Context, next: Next): Promise<void> => {\n try {\n await next();\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n\n // Log the error\n logger(err, ctx);\n\n // Check for custom handlers\n if (handlers) {\n for (const [ErrorType, handler] of handlers) {\n if (err instanceof ErrorType) {\n handler(err, ctx);\n return;\n }\n }\n }\n\n // Determine status code\n let status = 500;\n let expose = false;\n let code = 'INTERNAL_ERROR';\n let details: Record<string, unknown> | undefined;\n\n if (err instanceof HttpError || err instanceof NextRushError) {\n status = err.status;\n expose = err.expose;\n code = err.code;\n details = err.details;\n }\n\n ctx.status = status;\n\n // Build response body\n let body: Record<string, unknown>;\n\n if (transform) {\n body = transform(err, ctx);\n } else if (err instanceof NextRushError) {\n // Delegate to the error's own toJSON() — this is the single source of\n // truth for what a given error type serializes to (e.g. ValidationError\n // adds `issues` while stripping `received`). Duplicating that shape here\n // would silently drift out of sync with subclass overrides.\n body = err.toJSON();\n } else {\n body = {\n error: expose ? err.name : getHttpStatusMessage(status),\n message: expose ? err.message : 'Internal Server Error',\n code,\n status,\n };\n\n if (expose && details) {\n body.details = details;\n }\n }\n\n if (includeStack && err.stack) {\n body.stack = err.stack.split('\\n').map((line) => line.trim());\n }\n\n ctx.json(body);\n }\n };\n}\n\n/**\n * Not found handler middleware - catches unhandled requests\n *\n * @example\n * ```typescript\n * // Add at the end of middleware chain\n * app.use(notFoundHandler());\n * ```\n */\nexport function notFoundHandler(message = 'Not Found'): Middleware {\n return async (ctx: Context, next: Next): Promise<void> => {\n await next();\n // Only handle if no response was sent and status indicates unhandled\n if (!ctx.responded && ctx.status === 404) {\n ctx.json({\n error: 'NotFoundError',\n message,\n code: 'NOT_FOUND',\n status: 404,\n });\n }\n };\n}\n\n"],"mappings":"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","names":["ERROR_CODES","Object","freeze","codeForStatus","status","GENERIC_ERROR_CODE","VALIDATION_ERROR_CODE","V8Error","Error","MAX_CAUSE_DEPTH","serializeCause","cause","seen","depth","undefined","message","String","has","add","err","out","name","code","nested","NextRushError","status","expose","details","requestId","traceId","timestamp","options","Object","freeze","captureStackTrace","toJSON","json","error","serialized","Set","fromJSON","hydrate","build","getHttpStatusMessage","toResponse","body","HTTP_STATUS_MESSAGES","HttpError","codeForStatus","BadRequestError","HttpError","message","options","code","UnauthorizedError","PaymentRequiredError","ForbiddenError","NotFoundError","MethodNotAllowedError","allowedMethods","details","NotAcceptableError","ProxyAuthRequiredError","RequestTimeoutError","ConflictError","GoneError","LengthRequiredError","PreconditionFailedError","PayloadTooLargeError","UriTooLongError","UnsupportedMediaTypeError","RangeNotSatisfiableError","ExpectationFailedError","ImATeapotError","UnprocessableEntityError","LockedError","FailedDependencyError","TooEarlyError","UpgradeRequiredError","PreconditionRequiredError","TooManyRequestsError","retryAfter","undefined","RequestHeaderFieldsTooLargeError","UnavailableForLegalReasonsError","InternalServerError","expose","NotImplementedError","BadGatewayError","ServiceUnavailableError","GatewayTimeoutError","HttpVersionNotSupportedError","VariantAlsoNegotiatesError","InsufficientStorageError","LoopDetectedError","NotExtendedError","NetworkAuthRequiredError","ValidationError","NextRushError","issues","message","status","code","expose","Object","freeze","fromField","path","rule","fromFields","errors","entries","map","hasErrorFor","some","issue","getErrorsFor","filter","getFirstError","find","toFlatObject","result","toJSON","error","name","expected","undefined","RequiredFieldError","field","TypeMismatchError","received","RangeValidationError","min","max","parts","push","join","LengthError","PatternError","pattern","InvalidEmailError","InvalidUrlError","ERROR_MAP","BadRequestError","UnauthorizedError","PaymentRequiredError","ForbiddenError","NotFoundError","NotAcceptableError","ProxyAuthRequiredError","RequestTimeoutError","ConflictError","GoneError","LengthRequiredError","PreconditionFailedError","PayloadTooLargeError","UriTooLongError","UnsupportedMediaTypeError","RangeNotSatisfiableError","ExpectationFailedError","ImATeapotError","UnprocessableEntityError","LockedError","FailedDependencyError","TooEarlyError","UpgradeRequiredError","PreconditionRequiredError","TooManyRequestsError","RequestHeaderFieldsTooLargeError","UnavailableForLegalReasonsError","InternalServerError","NotImplementedError","BadGatewayError","ServiceUnavailableError","GatewayTimeoutError","HttpVersionNotSupportedError","VariantAlsoNegotiatesError","InsufficientStorageError","LoopDetectedError","NotExtendedError","NetworkAuthRequiredError","createError","status","message","options","MethodNotAllowedError","ErrorClass","HttpError","badRequest","unauthorized","forbidden","notFound","methodNotAllowed","allowedMethods","conflict","unprocessableEntity","tooManyRequests","internalError","badGateway","serviceUnavailable","gatewayTimeout","isHttpError","error","getErrorStatus","NextRushError","getSafeErrorMessage","expose","defaultLogger","error","ctx","status","HttpError","console","method","path","warn","message","errorHandler","options","includeStack","logger","transform","handlers","next","err","Error","String","ErrorType","handler","expose","code","details","NextRushError","body","toJSON","name","getHttpStatusMessage","stack","split","map","line","trim","json","notFoundHandler","responded"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextrush/errors",
3
- "version": "3.0.6",
3
+ "version": "4.0.0-beta.0",
4
4
  "description": "Standardized error handling for NextRush",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -18,12 +18,12 @@
18
18
  "README.md"
19
19
  ],
20
20
  "dependencies": {
21
- "@nextrush/types": "3.0.6"
21
+ "@nextrush/types": "4.0.0-beta.0"
22
22
  },
23
23
  "devDependencies": {
24
24
  "tsup": "^8.5.1",
25
- "typescript": "^6.0.2",
26
- "vitest": "^4.1.4"
25
+ "typescript": "^6.0.3",
26
+ "vitest": "^4.1.10"
27
27
  },
28
28
  "keywords": [
29
29
  "nextrush",
@@ -0,0 +1,181 @@
1
+ /**
2
+ * @nextrush/errors - Audit Remediation Tests
3
+ *
4
+ * Covers audit findings E-2 (cause serialization), E-3/E-4 (factory↔class code
5
+ * consistency + central registry), and E-6 (immutability).
6
+ */
7
+
8
+ import { describe, expect, it } from 'vitest';
9
+ import { HttpError, NextRushError } from '../base';
10
+ import { ERROR_CODES, codeForStatus } from '../codes';
11
+ import { createError } from '../factory';
12
+ import {
13
+ BadRequestError,
14
+ GoneError,
15
+ InternalServerError,
16
+ NotFoundError,
17
+ PayloadTooLargeError,
18
+ UnsupportedMediaTypeError,
19
+ } from '../http-errors';
20
+ import { ValidationError } from '../validation';
21
+
22
+ // ---------------------------------------------------------------------------
23
+ // E-3 / E-4 — factory returns the correctly-coded typed class; central registry
24
+ // ---------------------------------------------------------------------------
25
+
26
+ describe('E-3: createError returns the correctly-coded typed class', () => {
27
+ it('createError(413) is a PayloadTooLargeError with code PAYLOAD_TOO_LARGE (not HTTP_413)', () => {
28
+ const error = createError(413);
29
+ expect(error).toBeInstanceOf(PayloadTooLargeError);
30
+ expect(error.code).toBe('PAYLOAD_TOO_LARGE');
31
+ });
32
+
33
+ it('createError(415) is an UnsupportedMediaTypeError', () => {
34
+ expect(createError(415)).toBeInstanceOf(UnsupportedMediaTypeError);
35
+ expect(createError(415).code).toBe('UNSUPPORTED_MEDIA_TYPE');
36
+ });
37
+
38
+ it('createError(410) is a GoneError', () => {
39
+ expect(createError(410)).toBeInstanceOf(GoneError);
40
+ });
41
+
42
+ it('createError(status).code equals the direct class code for every registry status', () => {
43
+ for (const key of Object.keys(ERROR_CODES)) {
44
+ const status = Number(key);
45
+ // 405 has a divergent constructor signature; asserted separately.
46
+ if (status === 405) continue;
47
+ expect(createError(status).code).toBe(ERROR_CODES[status]);
48
+ }
49
+ });
50
+
51
+ it('still falls back to a generic HttpError for a status with no dedicated class', () => {
52
+ const error = createError(499);
53
+ expect(error).toBeInstanceOf(HttpError);
54
+ expect(error.status).toBe(499);
55
+ expect(error.code).toBe('HTTP_499');
56
+ });
57
+ });
58
+
59
+ describe('E-4: central code registry is the single source of truth', () => {
60
+ it('codeForStatus resolves canonical codes and falls back to HTTP_<status>', () => {
61
+ expect(codeForStatus(404)).toBe('NOT_FOUND');
62
+ expect(codeForStatus(413)).toBe('PAYLOAD_TOO_LARGE');
63
+ expect(codeForStatus(499)).toBe('HTTP_499');
64
+ });
65
+
66
+ it('a direct HttpError uses the canonical code from the registry', () => {
67
+ expect(new HttpError(404).code).toBe('NOT_FOUND');
68
+ expect(new HttpError(413).code).toBe('PAYLOAD_TOO_LARGE');
69
+ });
70
+ });
71
+
72
+ // ---------------------------------------------------------------------------
73
+ // E-2 — cause chain serialization (expose-gated, depth + cycle guarded)
74
+ // ---------------------------------------------------------------------------
75
+
76
+ describe('E-2: cause is serialized for exposed errors', () => {
77
+ it('includes a serialized cause on an exposed error', () => {
78
+ const cause = new Error('database offline');
79
+ const error = new BadRequestError('bad input', { cause });
80
+ const json = error.toJSON();
81
+ expect(json.cause).toMatchObject({ name: 'Error', message: 'database offline' });
82
+ });
83
+
84
+ it('propagates cause to the native Error so runtime tooling sees the chain', () => {
85
+ const cause = new Error('root');
86
+ const error = new BadRequestError('bad', { cause });
87
+ // Native Error.cause must be the same reference.
88
+ expect((error as Error).cause).toBe(cause);
89
+ });
90
+
91
+ it('does NOT leak cause on a non-exposed (5xx) error', () => {
92
+ const cause = new Error('secret internal detail');
93
+ const error = new InternalServerError('boom', { cause });
94
+ expect(error.toJSON().cause).toBeUndefined();
95
+ });
96
+
97
+ it('serializes a nested cause chain', () => {
98
+ const root = new Error('root failure');
99
+ const mid = new NextRushError('mid failure', { status: 400, cause: root });
100
+ const top = new NextRushError('top failure', { status: 400, cause: mid });
101
+ const json = top.toJSON();
102
+ const c1 = json.cause as { message: string; cause?: { message: string } };
103
+ expect(c1.message).toBe('mid failure');
104
+ expect(c1.cause?.message).toBe('root failure');
105
+ });
106
+
107
+ it('does not infinite-loop on a cyclic cause chain', () => {
108
+ const a = new Error('a') as Error & { cause?: unknown };
109
+ const b = new Error('b') as Error & { cause?: unknown };
110
+ a.cause = b;
111
+ b.cause = a;
112
+ const error = new NextRushError('c', { status: 400, cause: a });
113
+ expect(() => error.toJSON()).not.toThrow();
114
+ });
115
+ });
116
+
117
+ // ---------------------------------------------------------------------------
118
+ // E-6 — immutability of details and validation issues
119
+ // ---------------------------------------------------------------------------
120
+
121
+ describe('E-6: error details and validation issues are frozen', () => {
122
+ it('freezes details at construction', () => {
123
+ const error = new BadRequestError('x', { details: { field: 'email' } });
124
+ expect(Object.isFrozen(error.details)).toBe(true);
125
+ expect(() => {
126
+ (error.details as Record<string, unknown>).field = 'mutated';
127
+ }).toThrow(TypeError);
128
+ });
129
+
130
+ it('freezes ValidationError.issues at construction', () => {
131
+ const error = new ValidationError([{ path: 'email', message: 'required' }]);
132
+ expect(Object.isFrozen(error.issues)).toBe(true);
133
+ expect(() => {
134
+ (error.issues as unknown[]).push({ path: 'x', message: 'y' });
135
+ }).toThrow(TypeError);
136
+ });
137
+ });
138
+
139
+ // ---------------------------------------------------------------------------
140
+ // E-5 — correlation / trace identity
141
+ // ---------------------------------------------------------------------------
142
+
143
+ describe('E-5: errors carry optional correlation identity', () => {
144
+ it('stores requestId/traceId and surfaces them in toJSON when set', () => {
145
+ const error = new BadRequestError('x', { requestId: 'req-1', traceId: 'trace-1' });
146
+ expect(error.requestId).toBe('req-1');
147
+ expect(error.traceId).toBe('trace-1');
148
+ const json = error.toJSON();
149
+ expect(json.requestId).toBe('req-1');
150
+ expect(json.traceId).toBe('trace-1');
151
+ });
152
+
153
+ it('omits identity fields from toJSON when not set (no shape change by default)', () => {
154
+ const json = new BadRequestError('x').toJSON();
155
+ expect('requestId' in json).toBe(false);
156
+ expect('traceId' in json).toBe(false);
157
+ });
158
+ });
159
+
160
+ // ---------------------------------------------------------------------------
161
+ // E-7 — deserialization / wire round-trip
162
+ // ---------------------------------------------------------------------------
163
+
164
+ describe('E-7: HttpError.fromJSON reconstructs across a boundary', () => {
165
+ it('round-trips status, code, message, and details', () => {
166
+ const original = new NotFoundError('missing', { details: { id: 7 } });
167
+ const restored = HttpError.fromJSON(original.toJSON());
168
+ expect(restored).toBeInstanceOf(HttpError);
169
+ expect(restored).toBeInstanceOf(NextRushError);
170
+ expect(restored.status).toBe(404);
171
+ expect(restored.code).toBe('NOT_FOUND');
172
+ expect(restored.message).toBe('missing');
173
+ expect(restored.details).toEqual({ id: 7 });
174
+ });
175
+
176
+ it('restores correlation identity when present', () => {
177
+ const original = new BadRequestError('bad', { requestId: 'r-9' });
178
+ const restored = HttpError.fromJSON(original.toJSON());
179
+ expect(restored.requestId).toBe('r-9');
180
+ });
181
+ });
@@ -145,9 +145,9 @@ describe('HttpError', () => {
145
145
  expect(error.name).toBe('HttpError');
146
146
  });
147
147
 
148
- it('should set default code based on status', () => {
148
+ it('should set default code from the central registry based on status', () => {
149
149
  const error = new HttpError(404, 'Not found');
150
- expect(error.code).toBe('HTTP_404');
150
+ expect(error.code).toBe('NOT_FOUND');
151
151
  });
152
152
 
153
153
  it('should accept custom code', () => {
@@ -85,11 +85,18 @@ describe('createError', () => {
85
85
  expect(error).toBeInstanceOf(GatewayTimeoutError);
86
86
  });
87
87
 
88
- it('should create generic HttpError for unmapped status', () => {
88
+ it('should create a specific typed class for a mapped status (418)', () => {
89
89
  const error = createError(418);
90
90
  expect(error).toBeInstanceOf(HttpError);
91
91
  expect(error.status).toBe(418);
92
- expect(error.message).toBe("I'm a Teapot");
92
+ expect(error.code).toBe('IM_A_TEAPOT');
93
+ });
94
+
95
+ it('should create generic HttpError for an unmapped status', () => {
96
+ const error = createError(499);
97
+ expect(error).toBeInstanceOf(HttpError);
98
+ expect(error.status).toBe(499);
99
+ expect(error.code).toBe('HTTP_499');
93
100
  });
94
101
 
95
102
  it('should pass options to error', () => {
@@ -5,7 +5,8 @@
5
5
  import type { Context } from '@nextrush/types';
6
6
  import { describe, expect, it, vi } from 'vitest';
7
7
  import { BadRequestError, InternalServerError, NotFoundError } from '../http-errors';
8
- import { catchAsync, errorHandler, notFoundHandler } from '../middleware';
8
+ import { errorHandler, notFoundHandler } from '../middleware';
9
+ import { ValidationError } from '../validation';
9
10
 
10
11
  function createMockContext(): Context {
11
12
  const ctx = {
@@ -177,6 +178,42 @@ describe('errorHandler', () => {
177
178
  });
178
179
  });
179
180
 
181
+ describe('ValidationError serialization (regression)', () => {
182
+ it('includes `issues` in the response body for a ValidationError', async () => {
183
+ const handler = errorHandler();
184
+ const ctx = createMockContext();
185
+
186
+ await handler(ctx, async () => {
187
+ throw new ValidationError([
188
+ { path: 'body.email', message: 'Invalid email address' },
189
+ { path: 'body.name', message: 'Name is required' },
190
+ ]);
191
+ });
192
+
193
+ const jsonCall = (ctx.json as ReturnType<typeof vi.fn>).mock.calls[0][0];
194
+ expect(jsonCall.issues).toEqual([
195
+ { path: 'body.email', message: 'Invalid email address' },
196
+ { path: 'body.name', message: 'Name is required' },
197
+ ]);
198
+ expect(jsonCall.code).toBe('VALIDATION_ERROR');
199
+ expect(ctx.status).toBe(400);
200
+ });
201
+
202
+ it('never leaks the raw `received` value for a ValidationError', async () => {
203
+ const handler = errorHandler();
204
+ const ctx = createMockContext();
205
+
206
+ await handler(ctx, async () => {
207
+ throw new ValidationError([
208
+ { path: 'body.password', message: 'Invalid', received: 'super-secret-value' },
209
+ ]);
210
+ });
211
+
212
+ const jsonCall = (ctx.json as ReturnType<typeof vi.fn>).mock.calls[0][0];
213
+ expect(JSON.stringify(jsonCall)).not.toContain('super-secret-value');
214
+ });
215
+ });
216
+
180
217
  describe('handlers option', () => {
181
218
  it('should use custom handler for specific error type', async () => {
182
219
  const customHandler = vi.fn();
@@ -303,38 +340,6 @@ describe('notFoundHandler', () => {
303
340
  });
304
341
  });
305
342
 
306
- describe('catchAsync', () => {
307
- it('should pass through successful handlers', async () => {
308
- const innerHandler = vi.fn().mockResolvedValue(undefined);
309
- const handler = catchAsync(innerHandler);
310
- const ctx = createMockContext();
311
-
312
- await handler(ctx, noop);
313
-
314
- expect(innerHandler).toHaveBeenCalledWith(ctx, noop);
315
- });
316
-
317
- it('should re-throw errors', async () => {
318
- const error = new NotFoundError('Not found');
319
- const innerHandler = vi.fn().mockRejectedValue(error);
320
- const handler = catchAsync(innerHandler);
321
- const ctx = createMockContext();
322
-
323
- await expect(handler(ctx, noop)).rejects.toThrow(error);
324
- });
325
-
326
- it('should pass next to inner handler', async () => {
327
- const innerHandler = vi.fn().mockResolvedValue(undefined);
328
- const handler = catchAsync(innerHandler);
329
- const ctx = createMockContext();
330
- const next = vi.fn();
331
-
332
- await handler(ctx, next);
333
-
334
- expect(innerHandler).toHaveBeenCalledWith(ctx, next);
335
- });
336
- });
337
-
338
343
  describe('Integration scenarios', () => {
339
344
  it('should work with errorHandler and notFoundHandler together', async () => {
340
345
  const errHandler = errorHandler();