132 lines
3.2 KiB
JavaScript
132 lines
3.2 KiB
JavaScript
/**
|
|
* 自定义错误类 - 配置相关错误
|
|
*/
|
|
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,
|
|
};
|