|
@@ -16,22 +16,33 @@ from billiard.exceptions import ( # noqa
|
|
|
SoftTimeLimitExceeded, TimeLimitExceeded, WorkerLostError, Terminated,
|
|
|
)
|
|
|
|
|
|
-__all__ = ['SecurityError', 'Ignore', 'QueueNotFound',
|
|
|
- 'WorkerShutdown', 'WorkerTerminate',
|
|
|
- 'ImproperlyConfigured', 'NotRegistered', 'AlreadyRegistered',
|
|
|
- 'TimeoutError', 'MaxRetriesExceededError', 'Retry',
|
|
|
- 'TaskRevokedError', 'NotConfigured', 'AlwaysEagerIgnored',
|
|
|
- 'InvalidTaskError', 'ChordError', 'CPendingDeprecationWarning',
|
|
|
- 'CDeprecationWarning', 'FixupWarning', 'DuplicateNodenameWarning',
|
|
|
- 'SoftTimeLimitExceeded', 'TimeLimitExceeded', 'WorkerLostError',
|
|
|
- 'Terminated']
|
|
|
+__all__ = [
|
|
|
+ 'CeleryError', 'CeleryWarning', 'TaskPredicate',
|
|
|
+ 'SecurityError', 'Ignore', 'QueueNotFound',
|
|
|
+ 'WorkerShutdown', 'WorkerTerminate',
|
|
|
+ 'ImproperlyConfigured', 'NotRegistered', 'AlreadyRegistered',
|
|
|
+ 'TimeoutError', 'MaxRetriesExceededError', 'Retry',
|
|
|
+ 'TaskRevokedError', 'NotConfigured', 'AlwaysEagerIgnored',
|
|
|
+ 'InvalidTaskError', 'ChordError', 'CPendingDeprecationWarning',
|
|
|
+ 'CDeprecationWarning', 'FixupWarning', 'DuplicateNodenameWarning',
|
|
|
+ 'SoftTimeLimitExceeded', 'TimeLimitExceeded', 'WorkerLostError',
|
|
|
+ 'Terminated',
|
|
|
+]
|
|
|
|
|
|
UNREGISTERED_FMT = """\
|
|
|
Task of kind {0} is not registered, please make sure it's imported.\
|
|
|
"""
|
|
|
|
|
|
|
|
|
-class SecurityError(Exception):
|
|
|
+class CeleryError(Exception):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+class CeleryWarning(UserWarning):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+class SecurityError(CeleryError):
|
|
|
"""Security related exceptions.
|
|
|
|
|
|
Handle with care.
|
|
@@ -39,11 +50,55 @@ class SecurityError(Exception):
|
|
|
"""
|
|
|
|
|
|
|
|
|
-class Ignore(Exception):
|
|
|
+class TaskPredicate(CeleryError):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+class Retry(TaskPredicate):
|
|
|
+ """The task is to be retried later."""
|
|
|
+
|
|
|
+ #: Optional message describing context of retry.
|
|
|
+ message = None
|
|
|
+
|
|
|
+ #: Exception (if any) that caused the retry to happen.
|
|
|
+ exc = None
|
|
|
+
|
|
|
+ #: Time of retry (ETA), either :class:`numbers.Real` or
|
|
|
+ #: :class:`~datetime.datetime`.
|
|
|
+ when = None
|
|
|
+
|
|
|
+ def __init__(self, message=None, exc=None, when=None, **kwargs):
|
|
|
+ from kombu.utils.encoding import safe_repr
|
|
|
+ self.message = message
|
|
|
+ if isinstance(exc, string_t):
|
|
|
+ self.exc, self.excs = None, exc
|
|
|
+ else:
|
|
|
+ self.exc, self.excs = exc, safe_repr(exc) if exc else None
|
|
|
+ self.when = when
|
|
|
+ Exception.__init__(self, exc, when, **kwargs)
|
|
|
+
|
|
|
+ def humanize(self):
|
|
|
+ if isinstance(self.when, numbers.Real):
|
|
|
+ return 'in {0.when}s'.format(self)
|
|
|
+ return 'at {0.when}'.format(self)
|
|
|
+
|
|
|
+ def __str__(self):
|
|
|
+ if self.message:
|
|
|
+ return self.message
|
|
|
+ if self.excs:
|
|
|
+ return 'Retry {0}: {1}'.format(self.humanize(), self.excs)
|
|
|
+ return 'Retry {0}'.format(self.humanize())
|
|
|
+
|
|
|
+ def __reduce__(self):
|
|
|
+ return self.__class__, (self.message, self.excs, self.when)
|
|
|
+RetryTaskError = Retry # XXX compat
|
|
|
+
|
|
|
+
|
|
|
+class Ignore(TaskPredicate):
|
|
|
"""A task can raise this to ignore doing state updates."""
|
|
|
|
|
|
|
|
|
-class Reject(Exception):
|
|
|
+class Reject(TaskPredicate):
|
|
|
"""A task can raise this if it wants to reject/requeue the message."""
|
|
|
|
|
|
def __init__(self, reason=None, requeue=False):
|
|
@@ -72,86 +127,46 @@ class ImproperlyConfigured(ImportError):
|
|
|
"""Celery is somehow improperly configured."""
|
|
|
|
|
|
|
|
|
-class NotRegistered(KeyError):
|
|
|
+class NotRegistered(KeyError, CeleryError):
|
|
|
"""The task is not registered."""
|
|
|
|
|
|
def __repr__(self):
|
|
|
return UNREGISTERED_FMT.format(self)
|
|
|
|
|
|
|
|
|
-class AlreadyRegistered(Exception):
|
|
|
+class AlreadyRegistered(CeleryError):
|
|
|
"""The task is already registered."""
|
|
|
|
|
|
|
|
|
-class TimeoutError(Exception):
|
|
|
+class TimeoutError(CeleryError):
|
|
|
"""The operation timed out."""
|
|
|
|
|
|
|
|
|
-class MaxRetriesExceededError(Exception):
|
|
|
+class MaxRetriesExceededError(CeleryError):
|
|
|
"""The tasks max restart limit has been exceeded."""
|
|
|
|
|
|
|
|
|
-class Retry(Exception):
|
|
|
- """The task is to be retried later."""
|
|
|
-
|
|
|
- #: Optional message describing context of retry.
|
|
|
- message = None
|
|
|
-
|
|
|
- #: Exception (if any) that caused the retry to happen.
|
|
|
- exc = None
|
|
|
-
|
|
|
- #: Time of retry (ETA), either :class:`numbers.Real` or
|
|
|
- #: :class:`~datetime.datetime`.
|
|
|
- when = None
|
|
|
-
|
|
|
- def __init__(self, message=None, exc=None, when=None, **kwargs):
|
|
|
- from kombu.utils.encoding import safe_repr
|
|
|
- self.message = message
|
|
|
- if isinstance(exc, string_t):
|
|
|
- self.exc, self.excs = None, exc
|
|
|
- else:
|
|
|
- self.exc, self.excs = exc, safe_repr(exc) if exc else None
|
|
|
- self.when = when
|
|
|
- Exception.__init__(self, exc, when, **kwargs)
|
|
|
-
|
|
|
- def humanize(self):
|
|
|
- if isinstance(self.when, numbers.Real):
|
|
|
- return 'in {0.when}s'.format(self)
|
|
|
- return 'at {0.when}'.format(self)
|
|
|
-
|
|
|
- def __str__(self):
|
|
|
- if self.message:
|
|
|
- return self.message
|
|
|
- if self.excs:
|
|
|
- return 'Retry {0}: {1}'.format(self.humanize(), self.excs)
|
|
|
- return 'Retry {0}'.format(self.humanize())
|
|
|
-
|
|
|
- def __reduce__(self):
|
|
|
- return self.__class__, (self.message, self.excs, self.when)
|
|
|
-RetryTaskError = Retry # XXX compat
|
|
|
-
|
|
|
-
|
|
|
-class TaskRevokedError(Exception):
|
|
|
+class TaskRevokedError(CeleryError):
|
|
|
"""The task has been revoked, so no result available."""
|
|
|
|
|
|
|
|
|
-class NotConfigured(UserWarning):
|
|
|
+class NotConfigured(CeleryWarning):
|
|
|
"""Celery has not been configured, as no config module has been found."""
|
|
|
|
|
|
|
|
|
-class AlwaysEagerIgnored(UserWarning):
|
|
|
+class AlwaysEagerIgnored(CeleryWarning):
|
|
|
"""send_task ignores CELERY_ALWAYS_EAGER option"""
|
|
|
|
|
|
|
|
|
-class InvalidTaskError(Exception):
|
|
|
+class InvalidTaskError(CeleryError):
|
|
|
"""The task has invalid data or is not properly constructed."""
|
|
|
|
|
|
|
|
|
-class IncompleteStream(Exception):
|
|
|
+class IncompleteStream(CeleryError):
|
|
|
"""Found the end of a stream of data, but the data is not yet complete."""
|
|
|
|
|
|
|
|
|
-class ChordError(Exception):
|
|
|
+class ChordError(CeleryError):
|
|
|
"""A task part of the chord raised an exception."""
|
|
|
|
|
|
|
|
@@ -163,9 +178,9 @@ class CDeprecationWarning(DeprecationWarning):
|
|
|
pass
|
|
|
|
|
|
|
|
|
-class FixupWarning(UserWarning):
|
|
|
+class FixupWarning(CeleryWarning):
|
|
|
pass
|
|
|
|
|
|
|
|
|
-class DuplicateNodenameWarning(UserWarning):
|
|
|
+class DuplicateNodenameWarning(CeleryWarning):
|
|
|
"""Multiple workers are using the same nodename."""
|