• 【FastAPI 学习 六】异常处理


    异常处理

    统一捕获处理异常,使得代码更加完善,健壮。
    框架内置了一些异常,当然也可以自己定义异常然后捕获处理。

    完全可以参考官网(超喜欢这种风格的文档):
    https://fastapi.tiangolo.com/tutorial/handling-errors/

    异常捕获

    在FastAPI中,最常见的就是请求参数验证异常处理,因为FastAPI全面使用了pydantic来做数据类型校验,所以最常见的异常就是ValidationError , 然后FastAPI继承了这个错误,专门捕获请求参数异常的RequestValidationError

    捕获异常的语法

    from fastapi.exceptions import RequestValidationError
    
    @app.exception_handler(RequestValidationError)
    async def request_validation_exception_handler(request: Request, exc: RequestValidationError):
        """
        请求参数验证异常
        :param request: 请求头信息
        :param exc: 异常对象
        :return:
        """
        # 日志记录异常详细上下文 
        logger.error(f"全局异
    {request.method}URL{request.url}
    Headers:{request.headers}
    {traceback.format_exc()}")
        return response_code.resp_422(message=exc.errors())
    

    自定义异常

    我是这样做的,在utils/custom_exc.py文件下定义好各种异常

    class UserTokenError(Exception):
        def __init__(self, err_desc: str = "用户认证异常"):
            self.err_desc = err_desc
    
    
    class UserNotFound(Exception):
        def __init__(self, err_desc: str = "没有此用户"):
            self.err_desc = err_desc
    

    抛出自定异常

    先倒入异常,然后raise抛出

    from utils import custom_exc
    # xxxx
    raise custom_exc.UserTokenError(err_desc="access token fail")
    

    捕获自定异常

    这个和内置异常捕获语法是一样的

    @app.exception_handler(UserTokenError)
    async def user_token_exception_handler(request: Request, exc: UserTokenError):
    	"""
    	用户token异常
    	:param request:
    	:param exc:
    	:return:
    	"""
    	logger.error(f"用户认证异常
    URL:{request.url}
    Headers:{request.headers}
    {traceback.format_exc()}")
    	
    	return response_code.resp_5000(message=exc.err_desc)
    

    注册异常

    一般项目中会捕获各种异常, 最好就是把异常函数集中起来,我是模仿Flask框架来写的,所以FastAPI捕获异常语法也类似

    def create_app():
        """
        生成FatAPI对象
        :return:
        """
        app = FastAPI()
    
        # 其余的一些全局配置可以写在这里 多了可以考虑拆分到其他文件夹
    
        # 跨域设置
        # register_cors(app)
    
        # 注册路由
        # register_router(app)
    
        # 注册捕获全局异常
        register_exception(app)
    
        # 请求拦截
        # register_middleware(app)
        return app
    
    def register_static_file(app: FastAPI) -> None:
    	# 自定义异常 捕获
        @app.exception_handler(UserNotFound)
        async def user_not_found_exception_handler(request: Request, exc: UserNotFound):
            """
            用户认证未找到
            :param request:
            :param exc:
            :return:
            """
            logger.error(f"token未知用户
    URL:{request.url}
    Headers:{request.headers}
    {traceback.format_exc()}")
    
            return response_code.resp_5001(message=exc.err_desc)
            
        # 捕获全部异常
        @app.exception_handler(Exception)
        async def all_exception_handler(request: Request, exc: Exception):
            """
            全局所有异常
            :param request:
            :param exc:
            :return:
            """
            logger.error(f"全局异常
    {request.method}URL:{request.url}
    Headers:{request.headers}
    {traceback.format_exc()}")
            return response_code.resp_500(message="服务器内部错误")
    

    异常详情

    上一章博客有提过,使用traceback打印详细异常

    import traceback
    logger.error(traceback.format_exc())
    

    总结

    以上就是最基本的捕获异常的写法,捕获好异常,可以帮助更快更友好的排错,是接口返回格式更加规范。
    注意 捕获异常函数别手误写错了,多加个s, 写成@app.exception_handlers,就会报如下异常

    @app.exception_handlers(UserTokenError)
    TypeError: 'dict' object is not callable
    

    对应代码Github地址

    https://github.com/CoderCharm/fastapi-mysql-generator/blob/master/{{cookiecutter.project_name}}/app/common/custom_exc.py

    见个人网站 https://www.charmcode.cn/article/2020-07-19_fastapi_exception

  • 相关阅读:
    static生命周期
    VS2008 JS调试和Silverlight 后台代码调试 相互影响的问题。自己做实例证明
    思考记跳出以往的自己
    javascript setAttribute使用方法 查缺补漏
    克服浮躁,踏实工作,控制自我
    DES加密GUID+文件名称,关于DES加密后文件长度是否超过WINDOWS文件命名规定长度255个字节。
    阅读WPF揭秘前两章探索Silverlight运行的基本原理和RIA工作流程的密码()
    Silverlight运行原理经典问答。
    HTML 实用标签 (你不知道的HTML)
    ASP.NET项目整合 (Silverlight 和 WEB Service ) 过程及原理
  • 原文地址:https://www.cnblogs.com/CharmCode/p/14191103.html
Copyright © 2020-2023  润新知