UNPKG

@pulzar/core

Version:

Next-generation Node.js framework for ultra-fast web applications with zero-reflection DI, GraphQL, WebSockets, events, and edge runtime support

104 lines 4.08 kB
import { logger } from "../utils/logger"; export class ApiError extends Error { statusCode; details; constructor(message, statusCode = 500, details) { super(message); this.name = "ApiError"; this.statusCode = statusCode; if (details !== undefined) { this.details = details; } Error.captureStackTrace(this, ApiError); } } export class ErrorHandler { options; constructor(options = {}) { this.options = { includeStack: process.env.NODE_ENV === "development", customErrorCodes: {}, formatError: (error) => { const apiError = error; return { error: error.name || "Error", message: error.message, statusCode: apiError.statusCode || 500, ...(apiError.details && { details: apiError.details }), timestamp: new Date().toISOString(), }; }, ...options, }; } /** * Express error handling middleware */ middleware() { return (error, req, res, next) => { // Skip if response already sent if (res.headersSent) { return next(error); } // Get request ID const requestId = req.headers["x-request-id"] || "unknown"; // Log error logger.error("Request error", { error: error.message, stack: error.stack, statusCode: error.statusCode || 500, method: req.method, url: req.url, userAgent: req.headers["user-agent"], ip: req.ip, requestId, }); // Format error response const errorResponse = this.options.formatError(error); errorResponse.requestId = requestId; // Add stack trace in development if (this.options.includeStack && error.stack) { errorResponse.stack = error.stack; } // Determine status code const statusCode = error.statusCode || this.options.customErrorCodes[error.name] || 500; // Send error response res.status(statusCode).json(errorResponse); }; } /** * Create formatted error response */ formatError(error) { return this.options.formatError(error); } } // Default error handler instance export const errorHandler = new ErrorHandler(); // Error factory functions export const ApiErrors = { BadRequest: (message = "Bad Request", details) => new ApiError(message, 400, details), Unauthorized: (message = "Unauthorized", details) => new ApiError(message, 401, details), Forbidden: (message = "Forbidden", details) => new ApiError(message, 403, details), NotFound: (message = "Not Found", details) => new ApiError(message, 404, details), MethodNotAllowed: (message = "Method Not Allowed", details) => new ApiError(message, 405, details), Conflict: (message = "Conflict", details) => new ApiError(message, 409, details), UnprocessableEntity: (message = "Unprocessable Entity", details) => new ApiError(message, 422, details), TooManyRequests: (message = "Too Many Requests", details) => new ApiError(message, 429, details), InternalServerError: (message = "Internal Server Error", details) => new ApiError(message, 500, details), NotImplemented: (message = "Not Implemented", details) => new ApiError(message, 501, details), ServiceUnavailable: (message = "Service Unavailable", details) => new ApiError(message, 503, details), }; // Helper functions export function isApiError(error) { return error instanceof ApiError; } export function createErrorHandler(options) { return new ErrorHandler(options).middleware(); } // Default middleware export export default errorHandler.middleware(); //# sourceMappingURL=errorHandler.js.map