Forráskód Böngészése

`task.apply`: propagate=True now raises exceptions from the original frame, keeping the same stacktrace (Issue #256).

Christopher Peplin 14 éve
szülő
commit
50363eeaac
2 módosított fájl, 20 hozzáadás és 8 törlés
  1. 4 4
      celery/execute/__init__.py
  2. 16 4
      celery/execute/trace.py

+ 4 - 4
celery/execute/__init__.py

@@ -193,10 +193,10 @@ def apply(task, args, kwargs, **options):
                             if key in supported_keys)
     kwargs.update(extend_with)
 
-    trace = TaskTrace(task.name, task_id, args, kwargs, task=task)
+    trace = TaskTrace(task.name, task_id, args, kwargs,
+                      task=task, propagate=throw)
     retval = trace.execute()
     if isinstance(retval, ExceptionInfo):
-        if throw:
-            raise retval.exception
         retval = retval.exception
-    return EagerResult(task_id, retval, trace.status, traceback=trace.strtb)
+    return EagerResult(task_id, retval, trace.status,
+                       traceback=trace.strtb)

+ 16 - 4
celery/execute/trace.py

@@ -9,6 +9,7 @@ from celery.datastructures import ExceptionInfo
 
 
 class TraceInfo(object):
+
     def __init__(self, status=states.PENDING, retval=None, exc_info=None):
         self.status = status
         self.retval = retval
@@ -22,9 +23,13 @@ class TraceInfo(object):
             self.strtb = "\n".join(traceback.format_exception(*exc_info))
 
     @classmethod
-    def trace(cls, fun, args, kwargs):
+    def trace(cls, fun, args, kwargs, propagate=False):
         """Trace the execution of a function, calling the appropiate callback
-        if the function raises retry, an failure or returned successfully."""
+        if the function raises retry, an failure or returned successfully.
+
+        :keyword propagate: If true, errors will propagate to the caller.
+
+       """
         try:
             return cls(states.SUCCESS, retval=fun(*args, **kwargs))
         except (SystemExit, KeyboardInterrupt):
@@ -32,15 +37,20 @@ class TraceInfo(object):
         except RetryTaskError, exc:
             return cls(states.RETRY, retval=exc, exc_info=sys.exc_info())
         except Exception, exc:
+            if propagate:
+                raise
             return cls(states.FAILURE, retval=exc, exc_info=sys.exc_info())
         except:
             # For Python2.4 where raising strings are still allowed.
+            if propagate:
+                raise
             return cls(states.FAILURE, retval=None, exc_info=sys.exc_info())
 
 
 class TaskTrace(object):
 
-    def __init__(self, task_name, task_id, args, kwargs, task=None, **_):
+    def __init__(self, task_name, task_id, args, kwargs, task=None,
+            propagate=None, **_):
         self.task_id = task_id
         self.task_name = task_name
         self.args = args
@@ -48,6 +58,7 @@ class TaskTrace(object):
         self.task = task or tasks[self.task_name]
         self.status = states.PENDING
         self.strtb = None
+        self.propagate = propagate
         self._trace_handlers = {states.FAILURE: self.handle_failure,
                                 states.RETRY: self.handle_retry,
                                 states.SUCCESS: self.handle_success}
@@ -67,7 +78,8 @@ class TaskTrace(object):
         return retval
 
     def _trace(self):
-        trace = TraceInfo.trace(self.task, self.args, self.kwargs)
+        trace = TraceInfo.trace(self.task, self.args, self.kwargs,
+                                propagate=self.propagate)
         self.status = trace.status
         self.strtb = trace.strtb
         self.handle_after_return(trace.status, trace.retval,