You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用@app.errorhandler同时捕获多个异常类与HTTP状态码

问题根因

叠加@app.errorhandler装饰器本身是Flask官方支持的合法写法,你遇到的报错本质是Mypy对Flask装饰器的类型推断限制:

  • 当errorhandler接收自定义异常类作为参数时,要求被装饰函数的入参为对应异常类实例
  • 当errorhandler接收HTTP状态码作为参数时,要求被装饰函数的入参为HTTPException实例/状态码数值

两种场景对函数签名的要求存在差异,叠加装饰器时Mypy会以最外层装饰器的校验规则为准,就会出现顺序改变、参数名修改后报错的问题。

推荐实现方式

方式1:显式调用add_error_handler注册(无类型报错)

不需要叠加装饰器,直接通过Flask实例的方法显式注册两个处理规则,完全规避类型推断问题,可读性也更高:

class BadRequestError(Exception):
    pass

def serve_400_error(error: Exception) -> Response:
    return client_error_page(400)

# 分别注册状态码和自定义异常
app.add_error_handler(400, serve_400_error)
app.add_error_handler(BadRequestError, serve_400_error)

方式2:调整类型标注兼容装饰器写法

如果要保留装饰器叠加的写法,调整参数的类型标注,同时固定装饰器顺序:

from typing import Union
from werkzeug.exceptions import HTTPException

class BadRequestError(Exception):
    pass

# 装饰器顺序:异常类注册放在最下层,状态码注册放在上层
@app.errorhandler(400)
@app.errorhandler(BadRequestError)
def serve_400_error(error: Union[BadRequestError, HTTPException]) -> Response:
    return client_error_page(400)

如果要将参数名改为_且不需要用到参数,可以在参数后加忽略注释解决报错:

@app.errorhandler(400)
@app.errorhandler(BadRequestError)
def serve_400_error(_: Union[BadRequestError, HTTPException]) -> Response: # type: ignore[unused-argument]
    return client_error_page(400)

内容的提问来源于stack exchange,提问作者Garrett

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 21:54:03