UNPKG

@xilil/error-codes

Version:

统一错误码管理库 - 支持多语言、类型安全的错误处理工具

170 lines 6.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AppError = void 0; exports.getErrorCode = getErrorCode; exports.createErrorResponse = createErrorResponse; exports.createSuccessResponse = createSuccessResponse; exports.isOperationalError = isOperationalError; exports.getStatusCode = getStatusCode; exports.getAllErrorCodes = getAllErrorCodes; exports.findErrorKeyByCode = findErrorKeyByCode; exports.isValidErrorKey = isValidErrorKey; exports.expressErrorHandler = expressErrorHandler; exports.asyncHandler = asyncHandler; exports.throwError = throwError; exports.throwIf = throwIf; exports.assert = assert; const constants_1 = require("../constants"); function getErrorCode(errorKey, language = 'zh-CN') { const errorConfig = constants_1.ALL_ERROR_CODES[errorKey]; if (!errorConfig) { return { code: 1001, message: language === 'en-US' ? 'Internal server error' : '内部服务器错误', statusCode: 500, description: 'An internal server error occurred', }; } return { code: errorConfig.code, message: errorConfig.messages[language] || errorConfig.messages['zh-CN'], statusCode: errorConfig.statusCode, description: errorConfig.description || '', }; } function createErrorResponse(errorKey, language = 'zh-CN', path, data) { const errorCode = getErrorCode(errorKey, language); return { success: false, code: errorCode.code, message: errorCode.message, timestamp: Date.now(), path: path || '', data, }; } function createSuccessResponse(data, message, language = 'zh-CN') { return { code: 0, success: true, data, message: message || getErrorCode('SUCCESS', language).message, timestamp: Date.now(), }; } class AppError extends Error { constructor(errorKey, language, isOperational = true, details) { const errorCode = getErrorCode(errorKey, language); super(errorCode.message); this.errorKey = errorKey; this.language = language; this.code = errorCode.code; this.statusCode = errorCode.statusCode; this.isOperational = isOperational; this.details = details; if (Error.captureStackTrace) { Error.captureStackTrace(this, this.constructor); } } } exports.AppError = AppError; function isOperationalError(error) { if (error instanceof AppError) { return error.isOperational; } return false; } function getStatusCode(errorKey) { const errorConfig = constants_1.ALL_ERROR_CODES[errorKey]; return (errorConfig === null || errorConfig === void 0 ? void 0 : errorConfig.statusCode) || 500; } function getAllErrorCodes() { return constants_1.ALL_ERROR_CODES; } function findErrorKeyByCode(code) { for (const [key, config] of Object.entries(constants_1.ALL_ERROR_CODES)) { if (config.code === code) { return key; } } return undefined; } function isValidErrorKey(errorKey) { return errorKey in constants_1.ALL_ERROR_CODES; } function expressErrorHandler(defaultLanguage = 'zh-CN', enableStackTrace = process.env.NODE_ENV === 'development') { return (error, req, res, next) => { var _a, _b, _c, _d; if (res.headersSent) { return next(error); } let language = defaultLanguage; const acceptLanguage = req.headers['accept-language'] || req.headers['x-language']; if (acceptLanguage) { if (acceptLanguage.includes('en')) language = 'en-US'; else if (acceptLanguage.includes('zh')) language = 'zh-CN'; } let errorResponse; if (error instanceof AppError) { errorResponse = createErrorResponse(error.errorKey, error.language || language, req.originalUrl || req.url, error.details); console.error(`[AppError] ${error.errorKey}: ${error.message}`, { path: req.originalUrl || req.url, method: req.method, statusCode: error.statusCode, details: error.details, stack: enableStackTrace ? error.stack : undefined, }); const statusCode = req.headers['x-status'] === 'true' ? 200 : error.statusCode; return res.status(statusCode).json(errorResponse); } else { let errorKey = 'INTERNAL_ERROR'; if (error.name === 'ValidationError' || ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('validation'))) { errorKey = 'INVALID_PARAMETER'; } else if (error.name === 'UnauthorizedError' || ((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes('unauthorized'))) { errorKey = 'UNAUTHORIZED'; } else if (error.name === 'ForbiddenError' || ((_c = error.message) === null || _c === void 0 ? void 0 : _c.includes('forbidden'))) { errorKey = 'INSUFFICIENT_PERMISSIONS'; } else if (error.name === 'NotFoundError' || ((_d = error.message) === null || _d === void 0 ? void 0 : _d.includes('not found'))) { errorKey = 'RESOURCE_NOT_FOUND'; } errorResponse = createErrorResponse(errorKey, language, req.originalUrl || req.url, enableStackTrace ? { originalError: error.message, stack: error.stack, } : undefined); console.error(`[UnknownError] ${error.name}: ${error.message}`, { path: req.originalUrl || req.url, method: req.method, stack: error.stack, }); const statusCode = req.headers['x-status'] === 'true' ? 200 : error.statusCode || error.status || 500; return res.status(statusCode).json(errorResponse); } }; } function asyncHandler(fn) { return (req, res, next) => { Promise.resolve(fn(req, res, next)).catch(next); }; } function throwError(errorKey, details, language) { throw new AppError(errorKey, language, true, details); } function throwIf(condition, errorKey, details, language) { if (condition) { throw new AppError(errorKey, language, true, details); } } function assert(condition, errorKey, details, language) { if (!condition) { throw new AppError(errorKey, language, true, details); } } //# sourceMappingURL=index.js.map