关于 error-handling-standardizer
用于在应用中建立一致且便于调试的错误处理方式的开发技能,面向应用开发团队。内容涵盖错误分类、处理中间件、结构化日志、安全的客户端消息和异步错误包装。
主要功能
- 01定义自定义错误类与错误分类
- 02配置错误处理中间件及状态码映射
- 03记录带上下文的结构化日志
- 04向客户端返回安全错误消息
- 05包装异步路由错误
适用场景
- 01统一不同模块的错误响应
- 02避免向客户端泄露内部错误
- 03为请求错误添加日志上下文
- 04处理异步路由中的异常
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ patricio0312rev/ skills --skill error-handling-standardizer安装后在 Claude Code 中输入/error-handling-standardizer确认已加载。
详细介绍
错误处理标准化
在整个应用中构建一致且便于调试的错误处理机制。
错误分类
export class AppError extends Error {
constructor(
public code: string,
public message: string,
public statusCode: number = 500,
public isOperational: boolean = true,
public details?: any
) {
super(message);
Error.captureStackTrace(this, this.constructor);
}
}
export class ValidationError extends AppError {
constructor(details: Record<string, string[]>) {
super("VALIDATION_ERROR", "Validation failed", 400, true, details);
}
}
export class NotFoundError extends AppError {
constructor(resource: string) {
super("NOT_FOUND", `${resource} not found`, 404);
}
}
export class UnauthorizedError extends AppError {
constructor(message = "Unauthorized") {
super("UNAUTHORIZED", message, 401);
}
}
export class ForbiddenError extends AppError {
constructor(message = "Forbidden") {
super("FORBIDDEN", message, 403);
}
}
错误处理中间件
export const errorHandler = (
err: Error,
req: Request,
res: Response,
next: NextFunction
) => {
// Log error
logger.error("Request error", {
error: err.message,
stack: err.stack,
path: req.path,
method: req.method,
requestId: req.id,
});
// Operational errors (known)
if (err instanceof AppError && err.isOperational) {
return res.status(err.statusCode).json({
success: false,
error: {
code: err.code,
message: err.message,
details: err.details,
trace_id: req.id,
},
});
}
// Programming errors (unknown)
return res.status(500).json({
success: false,
error: {
code: "INTERNAL_ERROR",
message: "An unexpected error occurred",
trace_id: req.id,
},
});
};
结构化日志记录
import winston from "winston";
export const logger = winston.createLogger({
level: "info",
format: winston.format.combine(
winston.format.timestamp(),
winston.format.errors({ stack: true }),
winston.format.json()
),
transports: [
new winston.transports.File({ filename: "error.log", level: "error" }),
new winston.transports.File({ filename: "combined.log" }),
],
});
// Log with context
logger.error("Payment processing failed", {
userId: user.id,
amount: payment.amount,
error: err.message,
trace_id: req.id,
});
安全的客户端消息
// Never expose internal errors to clients
const getSafeErrorMessage = (err: Error): string => {
if (err instanceof AppError && err.isOperational) {
return err.message; // Safe, user-facing message
}
// Generic message for unexpected errors
return "An unexpected error occurred";
};
异步错误处理
// Wrap async routes
export const asyncHandler = (fn: RequestHandler) => {
return (req: Request, res: Response, next: NextFunction) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
};
// Usage
router.get(
"/users",
asyncHandler(async (req, res) => {
const users = await userService.findAll();
res.json(users);
})
);
最佳实践
- 使用自定义错误类
- 区分运行时错误与编程错误
- 记录所有错误及其上下文
- 切勿向客户端暴露堆栈跟踪
- 包含用于调试的跟踪 ID
- 按类型监控错误率
- 为严重错误设置告警
输出检查清单
- 已定义自定义错误类
- 已设置错误处理中间件
- 已映射 HTTP 状态码
- 已设置结构化日志记录
- 已设置安全的客户端错误消息
- 已设置异步错误包装器
- 已设置错误监控/告警
- 已编写错误代码文档
评论
支持 Markdown