Files
life-echo/api/app/core/error_codes.py

153 lines
3.9 KiB
Python
Raw Normal View History

"""
统一错误码注册表 OpenAPI 文档与客户端分支参考
HTTP 错误响应体``{ "error_code": str, "message": str, "request_id": str }``
"""
from __future__ import annotations
from typing import TypedDict
class ErrorCodeEntry(TypedDict):
code: str
http_status: int
domain: str
description: str
# ── 全局 / core AppError ─────────────────────────────────────
CORE_ERROR_CODES: list[ErrorCodeEntry] = [
{
"code": "BAD_REQUEST",
"http_status": 400,
"domain": "core",
"description": "请求无效(通用)",
},
{
"code": "AUTHENTICATION_FAILED",
"http_status": 401,
"domain": "core",
"description": "未认证或凭据无效",
},
{
"code": "FORBIDDEN",
"http_status": 403,
"domain": "core",
"description": "权限不足",
},
{
"code": "NOT_FOUND",
"http_status": 404,
"domain": "core",
"description": "资源不存在",
},
{
"code": "CONFLICT",
"http_status": 409,
"domain": "core",
"description": "资源冲突",
},
{
"code": "VALIDATION_ERROR",
"http_status": 422,
"domain": "core",
"description": "请求体验证失败",
},
{
"code": "QUOTA_EXCEEDED",
"http_status": 429,
"domain": "core",
"description": "配额已用尽",
},
{
"code": "RATE_LIMITED",
"http_status": 429,
"domain": "core",
"description": "请求频率超限(如 SMS 发送冷却)",
},
{
"code": "INTERNAL_ERROR",
"http_status": 500,
"domain": "core",
"description": "服务器内部错误",
},
{
"code": "PROVIDER_ERROR",
"http_status": 502,
"domain": "core",
"description": "外部服务异常(如短信发送失败)",
},
{
"code": "SERVICE_UNAVAILABLE",
"http_status": 503,
"domain": "core",
"description": "服务未配置或暂时不可用",
},
{
"code": "GATEWAY_TIMEOUT",
"http_status": 504,
"domain": "core",
"description": "网关超时",
},
]
# ── auth 领域AuthError────────────────────────────────────
AUTH_ERROR_CODES: list[ErrorCodeEntry] = [
{
"code": "PHONE_EXISTS",
"http_status": 400,
"domain": "auth",
"description": "手机号已注册",
},
{
"code": "EMAIL_EXISTS",
"http_status": 400,
"domain": "auth",
"description": "邮箱已注册",
},
{
"code": "INVALID_SMS_CODE",
"http_status": 400,
"domain": "auth",
"description": "短信验证码无效、过期或已使用",
},
{
"code": "WRONG_PASSWORD",
"http_status": 400,
"domain": "auth",
"description": "旧密码错误",
},
{
"code": "PHONE_TAKEN",
"http_status": 409,
"domain": "auth",
"description": "手机号已被其他账号占用",
},
{
"code": "REFRESH_TOKEN_REUSE",
"http_status": 401,
"domain": "auth",
"description": "刷新令牌在 grace 窗口外被重复使用或疑似盗用,全部会话已吊销",
},
]
# ── payment 领域PaymentError / order_service──────────────
PAYMENT_ERROR_CODES: list[ErrorCodeEntry] = [
{
"code": "PAYMENT_FAILED",
"http_status": 500,
"domain": "payment",
"description": "创建或处理支付订单失败",
},
]
ALL_ERROR_CODES: list[ErrorCodeEntry] = (
CORE_ERROR_CODES + AUTH_ERROR_CODES + PAYMENT_ERROR_CODES
)
ERROR_CODE_ENUM: list[str] = sorted({e["code"] for e in ALL_ERROR_CODES})