已用app.app_context()仍触发'Working outside' RuntimeError的解决办法
解决Celery Worker中「Working outside of application context」错误的问题
我一眼就发现问题所在了——你在创建Message对象的时候就已经触发了对Flask应用上下文的依赖,但这行代码是在app.app_context()上下文之外执行的!
看你的utils.py代码:
@celery.task def send_mail(subject, body, recipients): msg = Message(subject, recipients=recipients) # 这里就用到了current_app! msg.html = body with app.app_context(): mail.send(msg)
Flask-Mail的Message类在初始化时,会自动尝试从current_app里读取邮件扩展的默认发件人(也就是current_app.extensions['mail'].default_sender),这时候还没进入应用上下文,自然就抛出了那个RuntimeError。
解决办法很简单:把整个邮件处理逻辑都包裹在应用上下文里
修改后的utils.py应该是这样:
from ctflearn import db, celery, app, mail from flask_mail import Message @celery.task def send_mail(subject, body, recipients): with app.app_context(): msg = Message(subject, recipients=recipients) msg.html = body mail.send(msg)
额外的注意事项
- 确保启动Celery Worker时,你的应用实例能被正确导入。比如你用
celery -A ctflearn.celery worker --loglevel=info启动worker时,要在项目根目录下执行,保证ctflearn包的导入路径正确。 - 确认你在
__init__.py里初始化的app和mail对象是全局唯一的,不会在worker进程中被重新创建成新的实例。
内容的提问来源于stack exchange,提问作者Luke LaScala
相关产品推荐
相关产品推荐

