npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@aqcq/error-codes

v1.1.1

Published

统一错误码管理库 - 支持多语言、类型安全的错误处理工具

Downloads

18

Readme

@aqcq/error-codes

这是一个用于统一管理Express项目集合中错误码的 TypeScript 库。该库提供了标准化的错误码定义、多语言支持和完整的错误处理工具。

特性

  • 🌐 多语言支持: 支持中文和英文错误消息
  • 📋 分类管理: 按错误性质分类管理错误码(而非业务类型)
  • 🔧 类型安全: 完整的 TypeScript 类型定义
  • 🚀 零依赖: 不依赖外部库
  • 📊 HTTP 状态码映射: 错误码与 HTTP 状态码的智能映射
  • 🛠️ 工具函数: 丰富的错误处理工具函数
  • 🎯 Express 集成: 提供 Express 错误处理中间件

设计理念

🎯 按错误性质分类,而非业务类型

传统的按业务分类(如 CHAT_ERROR_CODES、FILE_ERROR_CODES)存在以下问题:

  • 业务耦合严重:新业务需要创建新的错误码分类
  • 错误码重复:相似错误在不同业务中被重复定义
  • 维护成本高:业务变更时需要修改错误码结构
  • 复用性差:错误码难以跨业务使用

✅ 新的设计原则

  1. 按错误性质分类:根据错误的本质特征进行分类
  2. 高度可复用:同一错误码可在多个业务中使用
  3. 易于维护:错误码结构稳定,不随业务变化
  4. 覆盖全面:预先定义常见的错误场景

错误码分类

1xxx - 系统内部错误码

用于系统级别的错误:

  • 1001 INTERNAL_ERROR - 内部服务器错误
  • 1002 SERVICE_UNAVAILABLE - 服务暂时不可用
  • 1003 CONFIGURATION_ERROR - 系统配置错误
  • 1004 EXTERNAL_SERVICE_ERROR - 外部服务调用失败

2xxx - 参数验证错误码

用于请求参数验证相关的错误:

  • 2001 INVALID_PARAMETER - 参数无效
  • 2002 MISSING_PARAMETER - 缺少必需参数
  • 2003 PARAMETER_OUT_OF_RANGE - 参数超出范围
  • 2004 INVALID_FORMAT - 格式不正确
  • 2005 CONTENT_TOO_LONG - 内容过长
  • 2006 UNSUPPORTED_TYPE - 不支持的类型

4xxx - 认证授权错误码

用于身份认证和权限相关的错误:

  • 4001 UNAUTHORIZED - 未授权访问
  • 4002 INVALID_TOKEN - 无效的令牌
  • 4003 TOKEN_EXPIRED - 令牌已过期
  • 4004 INSUFFICIENT_PERMISSIONS - 权限不足
  • 4005 ACCOUNT_DISABLED - 账户已被禁用
  • 4006 INVALID_CREDENTIALS - 认证信息无效
  • 4007 ACCOUNT_LOCKED - 账户已锁定
  • 4008 SESSION_EXPIRED - 会话已过期
  • 4009 ACCOUNT_NOT_FOUND - 账户不存在

41xx - 用户错误码

用于用户相关的错误

  • 4001 INVALID_INVITE_CODE - 邀请码无效

5xxx - 资源管理错误码

用于资源相关的错误:

  • 5001 RESOURCE_NOT_FOUND - 资源不存在
  • 5002 RESOURCE_ALREADY_EXISTS - 资源已存在
  • 5003 RESOURCE_CREATION_FAILED - 资源创建失败
  • 5004 RESOURCE_UPDATE_FAILED - 资源更新失败
  • 5005 RESOURCE_DELETE_FAILED - 资源删除失败
  • 5006 RESOURCE_IN_USE - 资源正在使用中
  • 5007 RESOURCE_LOCKED - 资源已被锁定

6xxx - 配额限制错误码

用于各种限制和配额相关的错误:

  • 6001 RATE_LIMIT_EXCEEDED - 请求频率超出限制
  • 6002 QUOTA_EXCEEDED - 配额已用完
  • 6003 STORAGE_QUOTA_EXCEEDED - 存储空间不足
  • 6004 CONCURRENT_LIMIT_EXCEEDED - 并发数超出限制
  • 6005 DAILY_LIMIT_EXCEEDED - 日使用量超出限制
  • 6006 SIZE_LIMIT_EXCEEDED - 大小超出限制

7xxx - 数据处理错误码

用于数据处理相关的错误:

  • 7001 DATA_CORRUPTION - 数据已损坏
  • 7002 SERIALIZATION_ERROR - 数据序列化失败
  • 7003 DESERIALIZATION_ERROR - 数据反序列化失败
  • 7004 DATA_TRANSFORMATION_ERROR - 数据转换失败
  • 7005 CHECKSUM_MISMATCH - 校验和不匹配

8xxx - 业务逻辑错误码

用于业务逻辑相关的错误:

  • 8001 BUSINESS_RULE_VIOLATION - 违反业务规则
  • 8002 OPERATION_NOT_ALLOWED - 操作不被允许
  • 8003 PREREQUISITE_NOT_MET - 前置条件未满足
  • 8004 WORKFLOW_ERROR - 工作流错误
  • 8005 STATE_CONFLICT - 状态冲突

9xxx - 第三方服务错误码

用于第三方服务集成相关的错误:

  • 9001 AI_SERVICE_ERROR - AI服务调用失败
  • 9002 AI_MODEL_UNAVAILABLE - AI模型不可用
  • 9003 PAYMENT_SERVICE_ERROR - 支付服务错误
  • 9004 SMS_SERVICE_ERROR - 短信服务错误
  • 9005 EMAIL_SERVICE_ERROR - 邮件服务错误
  • 9006 CLOUD_STORAGE_ERROR - 云存储服务错误
  • 9007 TRANSLATION_SERVICE_ERROR - 翻译服务错误
  • 9008 WECHAT_API_ERROR - 微信接口调用失败

安装

npm install @aqcq/error-codes

基本使用方法

错误码查询

import { getErrorCode, createErrorResponse, AppError } from '@sqcq/error-codes';

// 获取错误码信息
const error = getErrorCode('RESOURCE_NOT_FOUND', 'zh-CN');
console.log(error); 
// { code: 5001, message: '资源不存在', statusCode: 404, description: '请求的资源不存在' }

// 创建错误响应
const response = createErrorResponse('UNAUTHORIZED', 'zh-CN', '/api/user');
console.log(response);
// { success: false, code: 4001, message: '未授权访问', timestamp: 1699123456789, path: '/api/user' }

// 抛出应用错误
throw new AppError('AI_SERVICE_ERROR', 'zh-CN');

跨业务复用示例

import { 
  RESOURCE_ERROR_CODES, 
  VALIDATION_ERROR_CODES,
  AUTH_ERROR_CODES,
  createErrorResponse 
} from '@sqcq/error-codes';

// 聊天业务中使用
function getChatConversation(id: string) {
  if (!id) {
    return createErrorResponse('MISSING_PARAMETER', 'zh-CN');
  }
  
  if (!conversation) {
    return createErrorResponse('RESOURCE_NOT_FOUND', 'zh-CN');
  }
  
  if (!hasPermission) {
    return createErrorResponse('INSUFFICIENT_PERMISSIONS', 'zh-CN');
  }
}

// 文件业务中使用相同的错误码
function getFile(id: string) {
  if (!id) {
    return createErrorResponse('MISSING_PARAMETER', 'zh-CN');
  }
  
  if (!file) {
    return createErrorResponse('RESOURCE_NOT_FOUND', 'zh-CN');
  }
  
  if (!hasPermission) {
    return createErrorResponse('INSUFFICIENT_PERMISSIONS', 'zh-CN');
  }
}

业务场景映射

不同业务场景可以使用相同的通用错误码:

// 聊天业务错误映射
const ChatServiceErrors = {
  CONVERSATION_NOT_FOUND: 'RESOURCE_NOT_FOUND',
  MESSAGE_TOO_LONG: 'CONTENT_TOO_LONG',
  AI_MODEL_UNAVAILABLE: 'AI_MODEL_UNAVAILABLE',
  DAILY_LIMIT_EXCEEDED: 'DAILY_LIMIT_EXCEEDED'
} as const;

// 文件业务错误映射
const FileServiceErrors = {
  FILE_NOT_FOUND: 'RESOURCE_NOT_FOUND',
  FILE_TOO_LARGE: 'SIZE_LIMIT_EXCEEDED',
  INVALID_FILE_TYPE: 'UNSUPPORTED_TYPE',
  STORAGE_QUOTA_EXCEEDED: 'STORAGE_QUOTA_EXCEEDED'
} as const;

// 用户业务错误映射
const UserServiceErrors = {
  USER_NOT_FOUND: 'RESOURCE_NOT_FOUND',
  USER_ALREADY_EXISTS: 'RESOURCE_ALREADY_EXISTS',
  INVALID_PASSWORD: 'INVALID_CREDENTIALS',
  ACCOUNT_LOCKED: 'ACCOUNT_LOCKED'
} as const;

Express.js 错误处理

我们提供了专门为 Express 设计的错误处理中间件,让你可以直接通过 throw 抛出错误,自动返回标准化的错误响应给前端。

基本用法

import express from 'express';
import {
  AppError,
  expressErrorHandler,
  asyncHandler,
  throwError,
  throwIf,
  assert,
  createSuccessResponse
} from '@aqcq/error-codes';

const app = express();
app.use(express.json());

// 使用错误处理中间件(必须在所有路由之后)
app.use(expressErrorHandler('zh-CN', true));

// 路由示例
app.get('/api/users/:id', asyncHandler(async (req, res) => {
  const id = parseInt(req.params.id);
  
  // 方式1: 使用传统的 throw new AppError()
  if (isNaN(id)) {
    throw new AppError('INVALID_PARAMETER', 'zh-CN', true, { field: 'id' });
  }
  
  const user = await findUser(id);
  if (!user) {
    throw new AppError('RESOURCE_NOT_FOUND', 'zh-CN', true, { userId: id });
  }
  
  res.json(createSuccessResponse(user, '获取用户成功'));
}));

app.post('/api/users', asyncHandler(async (req, res) => {
  const { name, email } = req.body;
  
  // 方式2: 使用 throwError() 简化抛出错误
  if (!name) throwError('MISSING_PARAMETER', { field: 'name' });
  if (!email) throwError('MISSING_PARAMETER', { field: 'email' });
  
  // 方式3: 使用 throwIf() 条件抛出错误
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  throwIf(!emailRegex.test(email), 'INVALID_FORMAT', { field: 'email' });
  
  const existingUser = await findUserByEmail(email);
  throwIf(!!existingUser, 'RESOURCE_ALREADY_EXISTS', { email });
  
  const newUser = await createUser({ name, email });
  res.status(201).json(createSuccessResponse(newUser, '创建用户成功'));
}));

app.delete('/api/users/:id', asyncHandler(async (req, res) => {
  const id = parseInt(req.params.id);
  
  // 方式4: 使用 assert() 断言函数
  assert(!isNaN(id), 'INVALID_PARAMETER', { field: 'id' });
  
  const user = await findUser(id);
  assert(!!user, 'RESOURCE_NOT_FOUND', { userId: id });
  
  await deleteUser(id);
  res.json(createSuccessResponse(null, '删除用户成功'));
}));

app.listen(3000);

错误响应格式

所有错误都会返回统一的 JSON 格式:

{
  "success": false,
  "code": 5001,
  "message": "资源不存在",
  "timestamp": 1699123456789,
  "path": "/api/users/123",
  "data": {
    "userId": 123
  }
}

成功响应格式:

{
  "success": true,
  "data": { "id": 1, "name": "张三" },
  "message": "获取用户成功",
  "timestamp": 1699123456789
}

API 文档

类型定义

interface ErrorCode {
  code: number;
  message: string;
  statusCode: number;
  description?: string;
}

interface ErrorCodeConfig {
  code: number;
  messages: {
    'zh-CN': string;
    'en-US': string;
  };
  statusCode: number;
  description?: string;
}

interface ErrorResponse {
  success: false;
  code: number;
  data?: any;
  message: string;
  timestamp: number;
  path?: string;
}

interface SuccessResponse<T = any> {
  success: true;
  code: number;
  data: T;
  message?: string;
  timestamp: number;
}

type SupportedLanguage = 'zh-CN' | 'en-US';

核心函数

getErrorCode(errorKey: string, language?: SupportedLanguage): ErrorCode

获取指定错误键的错误信息。

const error = getErrorCode('RESOURCE_NOT_FOUND', 'zh-CN');
// { code: 5001, message: '资源不存在', statusCode: 404, description: '请求的资源不存在' }

createErrorResponse(errorKey: string, language?: SupportedLanguage, path?: string, data?: any): ErrorResponse

创建标准错误响应对象。

const response = createErrorResponse('UNAUTHORIZED', 'zh-CN', '/api/user', { reason: 'token_expired' });

createSuccessResponse<T>(data: T, message?: string, language?: SupportedLanguage): SuccessResponse<T>

创建标准成功响应对象。

const response = createSuccessResponse({ id: 1, name: '张三' }, '获取成功');

AppError

自定义错误类,继承自 Error。

throw new AppError('RESOURCE_NOT_FOUND', 'zh-CN', true, { userId: 123 });

Express 辅助函数

  • expressErrorHandler(defaultLanguage?, enableStackTrace?) - Express 错误处理中间件
  • asyncHandler(fn) - 异步错误包装器
  • throwError(errorKey, details?, language?) - 快速抛出错误
  • throwIf(condition, errorKey, details?, language?) - 条件抛出错误
  • assert(condition, errorKey, details?, language?) - 断言函数

工具函数

  • isOperationalError(error: Error): boolean - 判断是否为操作性错误
  • isValidErrorKey(key: string): boolean - 判断错误键是否有效
  • findErrorKeyByCode(code: number): string | undefined - 根据错误码查找对应的错误键
  • getStatusCode(errorKey: string): number - 获取错误键对应的HTTP状态码
  • getAllErrorCodes(): Record<string, ErrorCodeConfig> - 获取所有错误码配置

错误码完整列表

| 错误码 | 错误名称 | 中文描述 | 英文描述 | HTTP状态码 | |--------|----------|----------|----------|------------| | 系统内部错误码 | | 1001 | INTERNAL_ERROR | 内部服务器错误 | Internal server error | 500 | | 1002 | SERVICE_UNAVAILABLE | 服务暂时不可用 | Service temporarily unavailable | 503 | | 1003 | CONFIGURATION_ERROR | 系统配置错误 | System configuration error | 500 | | 1004 | EXTERNAL_SERVICE_ERROR | 外部服务调用失败 | External service call failed | 502 | | 参数验证错误码 | | 2001 | INVALID_PARAMETER | 参数无效 | Invalid parameter | 400 | | 2002 | MISSING_PARAMETER | 缺少必需参数 | Missing required parameter | 400 | | 2003 | PARAMETER_OUT_OF_RANGE | 参数超出范围 | Parameter out of range | 400 | | 2004 | INVALID_FORMAT | 格式不正确 | Invalid format | 400 | | 2005 | CONTENT_TOO_LONG | 内容过长 | Content too long | 400 | | 2006 | UNSUPPORTED_TYPE | 不支持的类型 | Unsupported type | 400 | | 认证授权错误码 | | 4001 | UNAUTHORIZED | 未授权访问 | Unauthorized access | 401 | | 4002 | INVALID_TOKEN | 无效的令牌 | Invalid token | 401 | | 4003 | TOKEN_EXPIRED | 令牌已过期 | Token expired | 401 | | 4004 | INSUFFICIENT_PERMISSIONS | 权限不足 | Insufficient permissions | 403 | | 4005 | ACCOUNT_DISABLED | 账户已被禁用 | Account disabled | 403 | | 4006 | INVALID_CREDENTIALS | 认证信息无效 | Invalid credentials | 401 | | 4007 | ACCOUNT_LOCKED | 账户已锁定 | Account locked | 423 | | 4008 | SESSION_EXPIRED | 会话已过期 | Session expired | 401 | | 4009 | ACCOUNT_NOT_FOUND | 用户不存在 | Account not found | 404 | | 用户错误码 | | 4101 | INVALID_INVITE_CODE | 邀请码无效 |Invalid invite code | 400 | | 资源管理错误码 | | 5001 | RESOURCE_NOT_FOUND | 资源不存在 | Resource not found | 404 | | 5002 | RESOURCE_ALREADY_EXISTS | 资源已存在 | Resource already exists | 409 | | 5003 | RESOURCE_CREATION_FAILED | 资源创建失败 | Resource creation failed | 500 | | 5004 | RESOURCE_UPDATE_FAILED | 资源更新失败 | Resource update failed | 500 | | 5005 | RESOURCE_DELETE_FAILED | 资源删除失败 | Resource deletion failed | 500 | | 5006 | RESOURCE_IN_USE | 资源正在使用中 | Resource is in use | 409 | | 5007 | RESOURCE_LOCKED | 资源已被锁定 | Resource is locked | 423 | | 配额限制错误码 | | 6001 | RATE_LIMIT_EXCEEDED | 请求频率超出限制 | Rate limit exceeded | 429 | | 6002 | QUOTA_EXCEEDED | 配额已用完 | Quota exceeded | 429 | | 6003 | STORAGE_QUOTA_EXCEEDED | 存储空间不足 | Storage quota exceeded | 507 | | 6004 | CONCURRENT_LIMIT_EXCEEDED | 并发数超出限制 | Concurrent limit exceeded | 429 | | 6005 | DAILY_LIMIT_EXCEEDED | 日使用量超出限制 | Daily limit exceeded | 429 | | 6006 | SIZE_LIMIT_EXCEEDED | 大小超出限制 | Size limit exceeded | 413 | | 数据处理错误码 | | 7001 | DATA_CORRUPTION | 数据已损坏 | Data corruption detected | 500 | | 7002 | SERIALIZATION_ERROR | 数据序列化失败 | Serialization failed | 500 | | 7003 | DESERIALIZATION_ERROR | 数据反序列化失败 | Deserialization failed | 400 | | 7004 | DATA_TRANSFORMATION_ERROR | 数据转换失败 | Data transformation failed | 500 | | 7005 | CHECKSUM_MISMATCH | 校验和不匹配 | Checksum mismatch | 400 | | 业务逻辑错误码 | | 8001 | BUSINESS_RULE_VIOLATION | 违反业务规则 | Business rule violation | 400 | | 8002 | OPERATION_NOT_ALLOWED | 操作不被允许 | Operation not allowed | 403 | | 8003 | PREREQUISITE_NOT_MET | 前置条件未满足 | Prerequisite not met | 412 | | 8004 | WORKFLOW_ERROR | 工作流错误 | Workflow error | 400 | | 8005 | STATE_CONFLICT | 状态冲突 | State conflict | 409 | | 第三方服务错误码 | | 9001 | AI_SERVICE_ERROR | AI服务调用失败 | AI service error | 502 | | 9002 | AI_MODEL_UNAVAILABLE | AI模型不可用 | AI model unavailable | 503 | | 9003 | PAYMENT_SERVICE_ERROR | 支付服务错误 | Payment service error | 502 | | 9004 | SMS_SERVICE_ERROR | 短信服务错误 | SMS service error | 502 | | 9005 | EMAIL_SERVICE_ERROR | 邮件服务错误 | Email service error | 502 | | 9006 | CLOUD_STORAGE_ERROR | 云存储服务错误 | Cloud storage error | 502 | | 9007 | TRANSLATION_SERVICE_ERROR | 翻译服务错误 | Translation service error | 502 | | 9008 | WECHAT_API_ERROR | 微信接口调用失败 | WeChat API error | 502 |

项目结构

error-codes/
├── src/
│   ├── constants/
│   │   ├── common.ts          # 通用成功/错误码
│   │   ├── business.ts        # 业务错误码(按性质分类)
│   │   └── index.ts           # 统一导出
│   ├── types/
│   │   └── index.ts           # 类型定义
│   ├── utils/
│   │   └── index.ts           # 工具函数和Express中间件
│   └── index.ts               # 主入口
├── examples/                  # 使用示例
├── __tests__/                 # 测试文件
├── package.json
└── README.md                  # 说明文档

最佳实践

1. 优先使用通用错误码

// ✅ 推荐 - 使用通用错误码
return createErrorResponse('RESOURCE_NOT_FOUND');

// ❌ 不推荐 - 创建业务特定错误码
return createErrorResponse('CHAT_CONVERSATION_NOT_FOUND');

2. 根据错误性质选择错误码

// 参数问题 -> 使用 2xxx 验证错误码
if (!isValidEmail(email)) {
  return createErrorResponse('INVALID_FORMAT');
}

// 资源问题 -> 使用 5xxx 资源错误码
if (!user) {
  return createErrorResponse('RESOURCE_NOT_FOUND');
}

// 权限问题 -> 使用 4xxx 认证错误码
if (!hasPermission) {
  return createErrorResponse('INSUFFICIENT_PERMISSIONS');
}

3. 创建业务特定的错误映射

// 为特定业务创建错误码映射,而不是创建新的错误码
export const ChatServiceErrors = {
  CONVERSATION_NOT_FOUND: 'RESOURCE_NOT_FOUND',
  MESSAGE_TOO_LONG: 'CONTENT_TOO_LONG',
  AI_SERVICE_ERROR: 'AI_SERVICE_ERROR',
  RATE_LIMIT_EXCEEDED: 'RATE_LIMIT_EXCEEDED'
} as const;

4. 使用 Express 中间件简化错误处理

// ✅ 推荐 - 使用中间件和便捷函数
app.get('/api/users/:id', asyncHandler(async (req, res) => {
  const id = parseInt(req.params.id);
  throwIf(isNaN(id), 'INVALID_PARAMETER', { field: 'id' });
  
  const user = await findUser(id);
  throwIf(!user, 'RESOURCE_NOT_FOUND', { userId: id });
  
  res.json(createSuccessResponse(user));
}));

// ❌ 不推荐 - 手动处理每个错误
app.get('/api/users/:id', async (req, res) => {
  try {
    const id = parseInt(req.params.id);
    if (isNaN(id)) {
      return res.status(400).json({
        success: false,
        message: '参数无效',
        // ... 重复的错误处理代码
      });
    }
    // ... 更多重复代码
  } catch (error) {
    // ... 手动错误处理
  }
});

扩展指南

当需要添加新的错误码时:

  1. 首先考虑现有错误码是否适用
  2. 如果需要新错误码,按错误性质归类
  3. 避免创建业务特定的错误码分类
  4. 保持错误码的通用性和可复用性

例如,如果需要添加新的限制类型错误:

// ✅ 添加到 QUOTA_ERROR_CODES
MONTHLY_LIMIT_EXCEEDED: {
  code: 6007,
  messages: {
    'zh-CN': '月使用量超出限制',
    'en-US': 'Monthly limit exceeded'
  },
  statusCode: 429,
  description: '月使用量已达到上限'
}

// ❌ 不要创建新的业务分类
VIDEO_SERVICE_ERROR_CODES: {
  // ...
}

开发

# 安装依赖
npm install

# 运行测试
npm test

# 构建
npm run build

# 运行演示
npm run demo

许可证

MIT License


通过按错误性质而非业务类型进行分类,我们实现了:

  • 高复用性:同一错误码可在多个业务中使用
  • 易维护性:错误码结构稳定,不随业务变化
  • 标准化:统一的错误处理方式
  • 可扩展性:易于添加新的错误类型

这种设计让错误码系统更加健壮和可持续发展。