根本原因是werkzeug重载机制fork子进程而vscode默认只附加主进程;必须用"module":"flask"模式启动,配"envfile"和"--no-reload"参数,并确保项目根目录打开、.env文件正确、断点置于路由函数内。

Flask调试时断点不进,根本不是代码问题
VSCode里跑Flask,断点打了却从不停——大概率是Werkzeug的--reload机制在fork子进程,而VSCode默认只attach主进程。你手动终端执行flask run能跑通,不代表调试器能跟上它的进程生命周期。
必须放弃"program": "app.py"这种写法。它绕过Flask CLI,导致热重载、flask shell、甚至request上下文都不可用,断点自然失效。
-
"module": "flask"是唯一可靠入口,强制走官方启动流程 -
.env文件(和app.py同级)必须存在,内容为:FLASK_APP=app.py(或工厂函数路径) - 项目必须用
File → Open Folder打开整个根目录,否则import和CLI路径全乱
launch.json里怎么配才能抓到异常和断点
核心字段只有三个:启动方式、参数、环境文件。其他都是干扰项。
"module": "flask" + "envFile": "${workspaceFolder}/.env" + "args": ["run", "--no-reload", "--debug"] 是最小可行配置。加--no-reload不是妥协,是调试阶段刚需——避免子进程切换导致断点丢失。
- 用工厂函数?把
args改成:["--app", "app:create_app", "run", "--no-reload", "--debug"],注意格式是模块名:函数名 - 别信插件自动生成的
Python: Flask模板,它硬编码FLASK_APP=app.py,换文件名就报No module named 'app' -
"justMyCode": false只在你想进Werkzeug源码时开,日常调试保持true,否则一抛异常就停在raise那行标准库代码里
为什么request对象报Working outside of application context
断点打在模块顶层、或者if __name__ == '__main__':块里,就永远拿不到request。Flask的上下文只在请求进入路由函数后才激活。
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
常见错误场景:
- Postman调API时没带
Content-Type: application/json,request.json就是None - 断点设在
@app.before_request钩子里,但钩子本身没上下文保障,得用has_request_context()兜底 -
app.run()还留在代码里没删——它和launch.json冲突,会导致双重启动、端口占用、上下文混乱
多线程模式下异常捕获失效的真实原因
Flask默认不启用多线程,app.run(threaded=True)只是让单个Worker处理多个请求,并不等于开启调试器对子线程的监听。真正影响异常捕获的是Werkzeug的reloader进程模型,不是线程数。
如果你非要保留热重载,"subProcess": true可以尝试让VSCode附加子进程,但它在Windows上成功率极低,且无法保证每次都能捕获到异常抛出处。
更稳的做法是:调试阶段关掉--reload,改完代码手动Ctrl+C再重启;上线前用gunicorn或uvicorn部署,它们的多进程/多线程模型和调试器兼容性更好。
最后提醒一句:.py文件保存编码要是UTF-8无BOM,BOM会导致ImportError,Werkzeug reload静默失败,你以为断点丢了,其实是进程根本没起来。










