mcpField
E
error-handling-standardizer

error-handling-standardizer

github.com/patricio0312rev开发63257 次安装41 周前更新
代码仓库

关于 error-handling-standardizer

用于在应用中建立一致且便于调试的错误处理方式的开发技能,面向应用开发团队。内容涵盖错误分类、处理中间件、结构化日志、安全的客户端消息和异步错误包装。

主要功能

  1. 01定义自定义错误类与错误分类
  2. 02配置错误处理中间件及状态码映射
  3. 03记录带上下文的结构化日志
  4. 04向客户端返回安全错误消息
  5. 05包装异步路由错误

适用场景

  1. 01统一不同模块的错误响应
  2. 02避免向客户端泄露内部错误
  3. 03为请求错误添加日志上下文
  4. 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