Skip to content

全局异常与响应

定义了统一的响应格式和全局异常处理机制。所有 API 返回 {code, data, msg, ok} 标准格式,异常被捕获后也转换为相同格式。响应函数位于 src/core/response.py,异常类型位于 src/core/exceptions.py

统一响应格式

src/core/response.py 提供统一的响应生成函数:

python
from core import response as R

# 成功响应
R.ok(data={"id": 1}, msg="操作成功")
# {"code": 0, "data": {"id": 1}, "msg": "操作成功", "ok": true}

# 成功响应(带额外字段)
R.ok(data=list, count=total)
# {"code": 0, "data": [...], "msg": "操作成功", "ok": true, "count": 100}

# 失败响应
R.failed(msg="参数错误")
# {"code": 1, "data": null, "msg": "参数错误", "ok": false}

响应函数说明

函数说明codeok
R.ok()成功响应0true
R.failed()失败响应1false
R.page()分页响应0true
R.response()通用响应自定义自定义

函数签名:

python
def ok(self, data=None, msg="操作成功", code=0, **kwargs) -> None:
    """生成成功响应,支持通过 kwargs 添加额外字段(如 count)"""

def failed(self, msg="操作失败", code=1, data=None, **kwargs) -> None:
    """生成失败响应"""

def page(self, data, total, current, size, msg="操作成功", code=0) -> None:
    """分页响应:封装 {records, total, size, current, pages} 标准分页结构"""

def response(self, data=None, msg="操作成功", code=0, success=True, **kwargs) -> None:
    """通用响应生成器(高级用法),允许完全自定义字段"""

分页响应

python
R.page(data=records, total=100, current=1, size=10)
# {
#     "code": 0,
#     "data": {
#         "records": [...],
#         "total": 100,
#         "size": 10,
#         "current": 1,
#         "pages": 10
#     },
#     "msg": "操作成功",
#     "ok": true
# }

异常类型

AuthError

认证异常,由 login_required 装饰器抛出:

python
# src/core/exceptions.py
class AuthError(BaseAppError):
    code = 401
    status_code = 401
    msg = "登录过期"

BusinessError

业务异常,业务代码可主动抛出:

python
class BusinessError(BaseAppError):
    msg = "操作失败"

使用示例:

python
from core.exceptions import BusinessError

def some_business_logic():
    if some_condition:
        raise BusinessError(msg="数据不存在")

全局异常处理

BaseHandler.write_error() 统一捕获异常并转换为标准格式:

python
# src/core/base_handler.py
class BaseHandler(tornado.web.RequestHandler):
    def write_error(self, status_code, **kwargs):
        exc = kwargs.get("exc_info", (None, None, None))[1]
        if isinstance(exc, BaseAppError):
            # 业务异常:按类型分级记录日志
            if isinstance(exc, (BusinessError, ValidationError, NotFoundError)):
                logger.warning("业务异常 path=%s msg=%s", self.request.path, exc.msg)
            else:
                logger.error("请求异常 path=%s msg=%s", self.request.path, exc.msg)
            self.set_status(exc.status_code)
            self.finish({"code": exc.code, "data": None, "msg": exc.msg, "ok": False})
        else:
            # 未预期异常:记录完整堆栈
            logger.error("未捕获异常 path=%s", self.request.path, exc_info=exc_info)
            self.set_status(500)
            self.finish({"code": 500, "data": None, "msg": "服务器内部错误", "ok": False})

异常处理机制

Tornado 通过 write_error() 方法统一处理异常。BaseAppError 及其子类会被捕获并转换为标准响应格式,未预期异常返回 500 错误码。

状态码常量

python
# src/core/response.py
class Codes:
 SUCCESS = 0
 FAILED = 1
 UNAUTHORIZED = 401 # 未认证
 FORBIDDEN = 403 # 无权限
 NOT_FOUND = 404 # 资源不存在
 VALIDATE_ERROR = 422 # 验证错误
 SERVER_ERROR = 500 # 服务器错误

总结

全局异常与响应模块具备以下特点:

1. 统一格式:所有 API 返回 {code, data, msg, ok} 标准格式
2. 全局捕获:认证异常、业务异常、HTTP异常、验证异常、未捕获异常
3. HTTP 200:所有响应均返回 200,业务状态通过 code 区分
4. 错误聚合:多个验证错误用 / 分隔,便于前端展示
5. 安全隐藏:未捕获异常返回通用提示,不暴露内部错误信息

小蚂蚁云团队 · 提供技术支持