跳转到主要内容

错误码参考

完整的 API 错误码列表,帮助您快速定位和解决问题。

预计阅读 16 分钟编辑此页

错误码参考#

本文档列出了 eBay AI 广告平台 Open API 可能返回的所有错误码,以及对应的处理建议。

错误响应格式#

当 API 请求失败时,会返回以下格式的 JSON 响应:

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "错误描述信息",
    "details": {
      "field": "额外的错误详情(可选)"
    },
    "request_id": "req_abc123xyz"
  }
}

响应字段说明#

| 字段 | 类型 | 说明 | |------|------|------| | success | boolean | 始终为 false | | error.code | string | 错误码(用于程序判断) | | error.message | string | 人类可读的错误描述 | | error.details | object | 额外的错误详情(如字段校验失败的具体字段) | | error.request_id | string | 请求 ID,用于问题排查 |

提示

遇到问题时,请提供 request_id 联系技术支持,我们可以快速定位问题。

错误码分类#

认证错误 (4xx)#

HTTP 状态码:401 Unauthorized403 Forbidden

| 错误码 | HTTP 状态 | 说明 | 解决方案 | |--------|-----------|------|----------| | UNAUTHORIZED | 401 | API Key 无效或未提供 | 检查 API Key 是否正确,是否包含 X-API-Key Header | | INVALID_SIGNATURE | 401 | 请求签名验证失败 | 检查签名算法实现,确保参数拼接顺序正确 | | TIMESTAMP_EXPIRED | 401 | 请求时间戳已过期 | 确保服务器时间准确,时间戳在 ±5 分钟内 | | API_KEY_DISABLED | 403 | API Key 已被禁用 | 联系管理员启用,或创建新的 API Key | | IP_NOT_ALLOWED | 403 | 请求 IP 不在白名单中 | 在控制台添加当前 IP 到白名单 | | PERMISSION_DENIED | 403 | 无权限访问该资源 | 检查 API Key 的权限配置 |

参数错误 (400)#

HTTP 状态码:400 Bad Request

| 错误码 | 说明 | 示例 | |--------|------|------| | INVALID_PARAMS | 请求参数校验失败 | 必填字段缺失、格式错误 | | INVALID_JSON | 请求体不是有效的 JSON | 检查 JSON 语法 | | MISSING_REQUIRED_FIELD | 缺少必填字段 | details.field 会指明缺失的字段 | | INVALID_FIELD_VALUE | 字段值不合法 | 如数值超出范围、枚举值无效 | | INVALID_DATE_FORMAT | 日期格式错误 | 应使用 YYYY-MM-DD 或 ISO 8601 格式 | | INVALID_ENUM_VALUE | 枚举值无效 | 检查允许的枚举值列表 |

参数错误响应示例#

{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "请求参数校验失败",
    "details": {
      "errors": [
        {
          "field": "budget_daily",
          "message": "日预算必须大于等于 1.00"
        },
        {
          "field": "name",
          "message": "活动名称不能超过 200 个字符"
        }
      ]
    },
    "request_id": "req_abc123"
  }
}

资源错误 (404)#

HTTP 状态码:404 Not Found

| 错误码 | 说明 | 解决方案 | |--------|------|----------| | RESOURCE_NOT_FOUND | 请求的资源不存在 | 检查资源 ID 是否正确 | | CAMPAIGN_NOT_FOUND | 广告活动不存在 | 确认活动 ID 存在且有访问权限 | | AD_GROUP_NOT_FOUND | 广告组不存在 | 确认广告组 ID 正确 | | KEYWORD_NOT_FOUND | 关键词不存在 | 确认关键词 ID 正确 | | EBAY_ACCOUNT_NOT_FOUND | eBay 账户不存在 | 确认账户已授权绑定 |

业务错误 (400/409)#

HTTP 状态码:400 Bad Request409 Conflict

| 错误码 | HTTP 状态 | 说明 | 解决方案 | |--------|-----------|------|----------| | QUOTA_EXCEEDED | 400 | 资源配额已用尽 | 升级套餐或删除不需要的资源 | | DUPLICATE_NAME | 409 | 名称已存在 | 使用不同的名称 | | INVALID_STATUS_TRANSITION | 400 | 状态转换不合法 | 检查当前状态和目标状态的转换规则 | | CAMPAIGN_BUDGET_TOO_LOW | 400 | 广告活动预算过低 | 日预算至少 1.00 美元 | | KEYWORD_BID_TOO_LOW | 400 | 关键词出价过低 | 出价至少 0.02 美元 | | KEYWORD_BID_TOO_HIGH | 400 | 关键词出价过高 | 检查出价上限设置 | | EBAY_ACCOUNT_NOT_AUTHORIZED | 400 | eBay 账户未授权或授权已过期 | 重新授权 eBay 账户 | | SYNC_IN_PROGRESS | 409 | 数据正在同步中 | 等待同步完成后重试 |

配额与限制 (429)#

HTTP 状态码:429 Too Many Requests

| 错误码 | 说明 | 解决方案 | |--------|------|----------| | RATE_LIMITED | 请求频率超过限制 | 降低请求频率,实现指数退避重试 | | DAILY_QUOTA_EXCEEDED | 日请求配额已用尽 | 等待次日配额重置,或升级套餐 | | CONCURRENT_LIMIT_EXCEEDED | 并发请求数超限 | 减少并发请求数 |

限流响应 Header#

当触发限流时,响应会包含以下 Header:

| Header | 说明 | |--------|------| | X-RateLimit-Limit | 当前时间窗口的请求上限 | | X-RateLimit-Remaining | 剩余可用请求数 | | X-RateLimit-Reset | 限额重置的 Unix 时间戳 | | Retry-After | 建议等待的秒数 |

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1704873660
Retry-After: 60

{
  "success": false,
  "error": {
    "code": "RATE_LIMITED",
    "message": "请求过于频繁,请稍后重试",
    "request_id": "req_abc123"
  }
}

外部服务错误 (502/503)#

HTTP 状态码:502 Bad Gateway503 Service Unavailable

| 错误码 | HTTP 状态 | 说明 | 解决方案 | |--------|-----------|------|----------| | EBAY_API_ERROR | 502 | eBay API 调用失败 | 稍后重试,如持续失败请联系支持 | | EBAY_API_TIMEOUT | 504 | eBay API 响应超时 | 稍后重试 | | SERVICE_UNAVAILABLE | 503 | 服务暂时不可用 | 系统维护中,请稍后重试 | | INTERNAL_ERROR | 500 | 服务器内部错误 | 记录 request_id 联系技术支持 |

服务器错误 (5xx)#

HTTP 状态码:500 Internal Server Error

| 错误码 | 说明 | 解决方案 | |--------|------|----------| | INTERNAL_ERROR | 服务器内部错误 | 记录 request_id 联系技术支持 | | DATABASE_ERROR | 数据库操作失败 | 稍后重试,如持续失败请联系支持 |

错误处理最佳实践#

1. 实现指数退避重试#

对于可重试的错误(如 RATE_LIMITEDSERVICE_UNAVAILABLE),建议实现指数退避重试:

import time
import random

def retry_with_backoff(func, max_retries=5, base_delay=1):
    """带指数退避的重试逻辑"""
    for attempt in range(max_retries):
        try:
            return func()
        except RateLimitError as e:
            if attempt == max_retries - 1:
                raise
            
            # 计算退避时间:base_delay * 2^attempt + 随机抖动
            delay = base_delay * (2 ** attempt) + random.uniform(0, 1)
            
            # 如果响应中有 Retry-After,优先使用
            if e.retry_after:
                delay = e.retry_after
            
            print(f"请求被限流,{delay:.1f}秒后重试...")
            time.sleep(delay)

2. 区分可重试与不可重试错误#

| 可重试 | 不可重试 | |--------|----------| | RATE_LIMITED | UNAUTHORIZED | | SERVICE_UNAVAILABLE | INVALID_SIGNATURE | | EBAY_API_TIMEOUT | INVALID_PARAMS | | INTERNAL_ERROR (偶发) | RESOURCE_NOT_FOUND | | SYNC_IN_PROGRESS | PERMISSION_DENIED |

3. 记录请求日志#

import logging

logger = logging.getLogger(__name__)

def handle_api_error(response):
    """处理 API 错误响应"""
    error = response.json().get('error', {})
    
    logger.error(
        "API 请求失败",
        extra={
            "error_code": error.get('code'),
            "message": error.get('message'),
            "request_id": error.get('request_id'),
            "status_code": response.status_code,
        }
    )
    
    # 根据错误码采取不同处理策略
    if error.get('code') == 'RATE_LIMITED':
        # 重试逻辑
        pass
    elif error.get('code') == 'INVALID_SIGNATURE':
        # 检查签名配置
        pass

4. 用户友好的错误提示#

将技术性错误码转换为用户友好的提示:

const ERROR_MESSAGES: Record<string, string> = {
  'UNAUTHORIZED': '认证失败,请检查 API 配置',
  'INVALID_SIGNATURE': '签名验证失败,请检查密钥配置',
  'RATE_LIMITED': '请求过于频繁,请稍后再试',
  'RESOURCE_NOT_FOUND': '请求的资源不存在',
  'QUOTA_EXCEEDED': '配额已用尽,请升级套餐',
  'EBAY_API_ERROR': 'eBay 服务暂时不可用,请稍后重试',
};

function getErrorMessage(code: string): string {
  return ERROR_MESSAGES[code] || '操作失败,请稍后重试';
}

常见问题排查#

签名验证失败 (INVALID_SIGNATURE)#

  1. 检查消息拼接顺序

    正确顺序:timestamp + method + path + body

    ✅ 正确: "1704873600GET/campaigns"
    ❌ 错误: "GET/campaigns1704873600"
    
  2. 检查 HTTP 方法大小写

    ✅ 正确: "GET", "POST", "PUT", "DELETE"
    ❌ 错误: "get", "post"
    
  3. 检查请求体一致性

    签名时使用的 body 必须与实际发送的完全一致,包括空格和顺序:

    ✅ 签名: {"name":"test","budget":100}
    ✅ 发送: {"name":"test","budget":100}
    
    ❌ 签名: {"name":"test","budget":100}
    ❌ 发送: {"budget":100,"name":"test"}  // 顺序不同
    
  4. 检查 API Secret

    确保没有多余的空格或换行符:

    # ✅ 正确
    API_SECRET = "sk_abcdef1234567890"
    
    # ❌ 错误
    API_SECRET = "sk_abcdef1234567890 "  # 末尾有空格
    API_SECRET = " sk_abcdef1234567890"  # 开头有空格
    

时间戳过期 (TIMESTAMP_EXPIRED)#

  1. 检查服务器时间

    # 检查当前时间
    date -u
    
    # 同步 NTP 时间
    sudo ntpdate pool.ntp.org
    
  2. 检查时区设置

    时间戳应为 UTC 时间:

    import time
    
    # ✅ 正确:UTC 时间戳
    timestamp = int(time.time())
    
    # ❌ 错误:使用本地时间可能导致偏差
    

资源不存在 (RESOURCE_NOT_FOUND)#

  1. 确认资源 ID 正确无误
  2. 确认资源属于当前 API Key 关联的租户
  3. 资源可能已被删除

获取帮助#

如果您无法解决问题,请通过以下方式联系我们:

  • 📧 发送邮件至 developer@eaby-ads.com
  • 💬 在开发者社区发帖
  • 📝 提交工单时请提供 request_id

相关链接#