
之前就的全局异常我们的是直接的在app.py的def __init_error_handlers(): 下注册的。根据中间件的模式,我们也可以迁移到中间件去处理,类似Go框架的Gin做一个全局的异常的中间件异常捕获。
PS:需要注意点是,我们的中间件的注册异常的函数的时候,不能像之前的使用 self.app.before_request(self.__before_request)的方式进行调用了。
还是需要保持为:@self.app.errorhandler(Exception)的方式进行注册异常捕获。
完整中间件代码为:
#!/usr/bin/evn python
# coding=utf-8
from common.exc import *
from loguru import logger
class MiddlewareErrorHandler():
def __init__(self, *args, **kwargs):
pass
def init_app(self, app, _is_handlers_aout=True):
self.app = app
if _is_handlers_aout:
pass
self.register_handlers()
return self
def register_handlers(self):
# 不能使用的调用函数的形式,原因暂时未知
@self.app.errorhandler(Exception)
def custom_error_handler(e):
if isinstance(e, ApiAdminJsonResponse):
# 直接的再次的返回,这样在From中也可以直接的返回了!
# 如果还需要其他自定义的返回提示,可以再这里再进行判断,比如,我想直接返回200的响应体信息的话
return e
if isinstance(e, HTTPException):
if e.code == 429:
limt = LimiterResException()
limt.msg = limt.msg + ' ' + e.description
return limt
if e.code == 404:
return NotfoundException()
if e.code == 404:
return NotfoundException()
# 其他错误处理------------------ 它跑到了全局了去
code = e.code
msg = e.description
api_code = 20000
return OtherException(message=msg, code=code, api_code=api_code)
else:
# 如果是Debug
if not self.app.config['DEBUG']:
logger.exception(e)
return InternalErrorException()
else:
# 本地开始直接带打印
raise e
# import traceback
# app.logger.error(traceback.format_exc())
# return UnknownException()
完整中间件代码为:
#!/usr/bin/evn python
# coding=utf-8
from flask import request
from common.exc import ForbiddenException, InvalidTokenException,ExpiredTokenException
from common.ext.jwt import Auth
class MiddlewareCors():
def __init__(self, *args, **kwargs):
pass
# 定义头部提交自定义的请求头
self.token_key = 'X-Access-Token'
# HTTP_TOKEN
def init_app(self, app, _is_handlers_aout=True):
self.app = app
if _is_handlers_aout:
self.register_handlers()
return self
def __after_request(self, response):
# # 注册跨域
response.headers['Access-Control-Allow-Origin'] = '*'
response.headers['Access-Control-Allow-Credentials'] = 'true'
# response.headers['Access-Control-Allow-Origin'] = '*'
# 注意这里的方法的名称,或直接的写GET,POST,PUT,OPTIONS,DELETE
response.headers['Access-Control-Allow-Methods'] = 'GET,POST,PUT,OPTIONS,DELETE'
response.headers['Access-Control-Allow-Headers'] = '*'
# response.headers['Access-Control-Allow-Headers'] = '*222222222'
# 这个地方不能直接的写* 号, 当前端发起跨域 解决axios出现的Request header is not allowed by Access-Control-Allow-Headers in preflight response
# 需要明确支持的头部信息
# login2323?redirect=%2F:1 XMLHttpRequest cannot load http://ikp5c9.natappfree.cc/sys/login. Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response
# 奇葩的UC 浏览器
# 奇葩的UC 浏览器--注意一点 涉及到跨域的时候,涉及自定义头部信息的时候,都需要再次加上
allow_headers = '*,School-Teacher-Token,school-teacher-token,T-Access-Token,x-access-token,Referer, Accept, Origin, User-Agent,X-Requested-With, Content-Type, X-File-Name'
response.headers['Access-Control-Allow-Headers'] = allow_headers
# response.headers['Access-Control-Allow-Headers'] =response.headers['Access-Control-Allow-Headers']
return response
def register_handlers(self):
self.app.after_request(self.__after_request)
注意修改我们的中间件注册顺序,然后启动服务测试,我们的中间件能正常捕获异常和进行跨域处。
小钟同学 | 文 【原创】【转载请联系本人】| QQ:308711822
原文作者:程序员小钟同学;如有侵权,请联系管理员删除。