File size: 3,260 Bytes
e1ae2c6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | /**
* 自定义错误类 - 配置相关错误
*/
class ConfigError extends Error {
constructor(message, suggestions = []) {
super(message);
this.name = 'ConfigError';
this.suggestions = suggestions;
}
}
/**
* 自定义错误类 - 模板相关错误
*/
class TemplateError extends Error {
constructor(message, templatePath = null) {
super(message);
this.name = 'TemplateError';
this.templatePath = templatePath;
}
}
/**
* 自定义错误类 - 构建相关错误
*/
class BuildError extends Error {
constructor(message, context = {}) {
super(message);
this.name = 'BuildError';
this.context = context;
}
}
/**
* 自定义错误类 - 文件操作相关错误
*/
class FileError extends Error {
constructor(message, filePath = null, suggestions = []) {
super(message);
this.name = 'FileError';
this.filePath = filePath;
this.suggestions = suggestions;
}
}
/**
* 统一错误处理器 - 专业紧凑版(中文)
* @param {Error} error - 错误对象
* @param {number} exitCode - 退出码,默认为 1
*/
function handleError(error, exitCode = 1) {
const { formatPrefix, isVerbose } = require('./logger');
// 错误标题行
console.error(`\n${formatPrefix('ERROR')} ${error.name}: ${error.message}`);
// 文件路径(如果有)
if (error.filePath || error.templatePath) {
const path = error.filePath || error.templatePath;
console.error(`位置: ${path}`);
}
// 上下文信息(如果有)
if (error.context && Object.keys(error.context).length > 0) {
console.error('上下文:');
for (const [key, value] of Object.entries(error.context)) {
console.error(` ${key}: ${value}`);
}
}
// 修复建议(如果有)
if (error.suggestions && error.suggestions.length > 0) {
console.error('建议:');
error.suggestions.forEach((suggestion, index) => {
console.error(` ${index + 1}) ${suggestion}`);
});
}
// DEBUG 提示(仅在非 DEBUG 模式下显示)
if (process.env.DEBUG) {
console.error('\n堆栈:');
console.error(error.stack || String(error));
} else if (isVerbose() && error && error.stack) {
console.error('\n堆栈:');
console.error(error.stack);
} else {
console.error('\n提示: DEBUG=1 查看堆栈');
}
console.error(); // 空行结束
process.exit(exitCode);
}
/**
* 包装异步函数,自动处理未捕获的错误
* @param {Function} fn - 异步函数
* @returns {Function} 包装后的函数
*/
function wrapAsyncError(fn) {
return async (...args) => {
try {
return await fn(...args);
} catch (error) {
// 如果是自定义错误,直接使用 handleError
if (
error instanceof ConfigError ||
error instanceof TemplateError ||
error instanceof BuildError ||
error instanceof FileError
) {
handleError(error);
} else {
// 否则包装为 BuildError
handleError(
new BuildError(error.message || '未知错误', {
原始错误类型: error.name || 'Error',
})
);
}
}
};
}
module.exports = {
ConfigError,
TemplateError,
BuildError,
FileError,
handleError,
wrapAsyncError,
};
|