refactor: 统一错误处理机制

- 引入 ConfigError/TemplateError/BuildError/FileError 与 wrapAsyncError,统一错误输出
- generator 入口接入 wrapAsyncError,确保命令行执行路径一致
- 兜底逻辑使用 instanceof,保留 BuildError/TemplateError 上下文信息
- 合并格式化提交(仅缩进/换行调整)
This commit is contained in:
rbetree
2026-01-16 02:25:03 +08:00
parent 1a90f8fbe3
commit 89c1c0330b
31 changed files with 313 additions and 89 deletions

View File

@@ -0,0 +1,127 @@
/**
* 自定义错误类 - 配置相关错误
*/
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) {
// 错误标题行
console.error(`\n${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('│');
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);
} 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,
};