@xilil/error-codes
Version:
统一错误码管理库 - 支持多语言、类型安全的错误处理工具
170 lines • 6.6 kB
JavaScript
;
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