فهرست منبع

Fix celery ignores exceptions raised during `django.setup()` (#4146)

* Check `import_modules.send`’s return value in `import_default_modules`, make sure no exception is silenced.

* Fix codestyle issues.
Kevin Gu 7 سال پیش
والد
کامیت
13916dee1b
2فایلهای تغییر یافته به همراه18 افزوده شده و 1 حذف شده
  1. 7 1
      celery/loaders/base.py
  2. 11 0
      t/unit/app/test_loaders.py

+ 7 - 1
celery/loaders/base.py

@@ -107,7 +107,13 @@ class BaseLoader(object):
         )
 
     def import_default_modules(self):
-        signals.import_modules.send(sender=self.app)
+        responses = signals.import_modules.send(sender=self.app)
+        # Prior to this point loggers are not yet set up properly, need to
+        #   check responses manually and reraised exceptions if any, otherwise
+        #   they'll be silenced, making it incredibly difficult to debug.
+        for _, response in responses:
+            if isinstance(response, Exception):
+                raise response
         return [self.import_task_module(m) for m in self.default_modules]
 
     def init_worker(self):

+ 11 - 0
t/unit/app/test_loaders.py

@@ -88,6 +88,17 @@ class test_LoaderBase:
         assert (sorted(modnames(self.loader.import_default_modules())) ==
                 sorted(modnames([os, sys])))
 
+    def test_import_default_modules_with_exception(self):
+        """ Make sure exceptions are not silenced since this step is prior to
+            setup logging. """
+        def trigger_exception(**kwargs):
+            raise ImportError('Dummy ImportError')
+        from celery.signals import import_modules
+        import_modules.connect(trigger_exception)
+        self.app.conf.imports = ('os', 'sys')
+        with pytest.raises(ImportError):
+            self.loader.import_default_modules()
+
     def test_import_from_cwd_custom_imp(self):
         imp = Mock(name='imp')
         self.loader.import_from_cwd('foo', imp=imp)