Flask Traceback仅显示外部库,无法定位自有代码错误行原因咨询
问题
运行Flask应用时遇到500错误,对应的Traceback只显示外部库的调用栈信息,没法定位到自有代码里引发错误的具体行;但写小型测试应用复现该错误时,Traceback却能正常显示错误行号,想知道这一现象的原因。
正式应用错误信息
* Debugger is active! * Debugger PIN: ****** 127.0.0.1 - - [29/Dec/2022 12:21:53] "GET /authorization/****/authorize HTTP/1.1" 302 - 127.0.0.1 - - [29/Dec/2022 12:21:53] "GET /authorization/****/test HTTP/1.1" 500 - Traceback (most recent call last): File "******/lib/python3.10/site-packages/flask/app.py", line 2548, in __call__ return self.wsgi_app(environ, start_response) File "******/lib/python3.10/site-packages/flask/app.py", line 2528, in wsgi_app response = self.handle_exception(e) File "******/lib/python3.10/site-packages/flask/app.py", line 2525, in wsgi_app response = self.full_dispatch_request() File "******/lib/python3.10/site-packages/flask/app.py", line 1823, in full_dispatch_request return self.finalize_request(rv) File "******/lib/python3.10/site-packages/flask/app.py", line 1844, in finalize_request response = self.process_response(response) File "******/lib/python3.10/site-packages/flask/app.py", line 2340, in process_response self.session_interface.save_session(self, ctx.session, response) File "******/lib/python3.10/site-packages/flask/sessions.py", line 409, in save_session val = self.get_signing_serializer(app).dumps(dict(session)) # type: ignore File "******/lib/python3.10/site-packages/itsdangerous/serializer.py", line 207, in dumps payload = want_bytes(self.dump_payload(obj)) File "******/lib/python3.10/site-packages/itsdangerous/url_safe.py", line 53, in dump_payload json = super().dump_payload(obj) File "******/lib/python3.10/site-packages/itsdangerous/serializer.py", line 169, in dump_payload return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs)) File "******/lib/python3.10/site-packages/flask/json/tag.py", line 308, in dumps return dumps(self.tag(value), separators=(",", ":")) File "******/lib/python3.10/site-packages/flask/json/__init__.py", line 124, in dumps return app.json.dumps(obj, **kwargs) File "******/lib/python3.10/site-packages/flask/json/provider.py", line 230, in dumps return json.dumps(obj, **kwargs) File "/usr/lib/python3.10/json/__init__.py", line 238, in dumps **kw).encode(obj) File "/usr/lib/python3.10/json/encoder.py", line 199, in encode chunks = self.iterencode(o, _one_shot=True) File "/usr/lib/python3.10/json/encoder.py", line 257, in iterencode return _iterencode(o, 0) File "******/lib/python3.10/site-packages/flask/json/provider.py", line 122, in _default raise TypeError(f"Object of type {type(o).__name__} is not JSON serializable")
测试应用代码
import flask import json app = flask.Flask(__name__) app.secret_key = "####" @app.route("/") def index(): json.dumps(json) # Line that causes error if __name__ == "__main__": app.run("localhost", 8080, debug=True)
原因分析
错误触发时机差异:
正式应用的错误是在视图函数执行完毕后,Flask进入process_response阶段保存session时触发的。这个过程属于框架内部的后续处理,和你的业务代码已经不在同一调用栈,所以Traceback只会展示框架库的调用信息,无法关联到你写入session的代码行。
测试应用的错误是在视图函数内部直接调用序列化函数时即时触发,调用栈自然包含你的业务代码行。错误根源的间接性:
正式应用的问题本质是你在某个业务逻辑中往session存入了无法JSON序列化的对象,但存入操作本身不会立刻报错,直到Flask尝试序列化session时才暴露问题。此时错误栈只能追踪到框架执行序列化的代码,无法回溯到原始的存入操作位置。
测试应用的错误是直接在视图中触发序列化失败,错误栈直接指向问题代码。代码复杂度与框架流程的包裹:
正式应用可能包含更多中间件、扩展或复杂的代码结构,导致错误被框架的异常处理流程多层包裹,进一步掩盖了原始调用栈中业务代码的痕迹。
内容的提问来源于stack exchange,提问作者Raphael
相关产品推荐
相关产品推荐

