mirror of
https://github.com/pretix/pretix.git
synced 2026-05-17 17:14:04 +00:00
Separate exception types
This commit is contained in:
@@ -81,12 +81,35 @@ def sync_all():
|
|||||||
sync_event_to_target(event, target_cls, queued_orders)
|
sync_event_to_target(event, target_cls, queued_orders)
|
||||||
|
|
||||||
|
|
||||||
class SyncConfigError(Exception):
|
class BaseSyncError(Exception):
|
||||||
def __init__(self, messages, full_message=None):
|
def __init__(self, messages, full_message=None):
|
||||||
self.messages = messages
|
self.messages = messages
|
||||||
self.full_message = full_message
|
self.full_message = full_message
|
||||||
|
|
||||||
|
|
||||||
|
class UnrecoverableSyncError(BaseSyncError):
|
||||||
|
"""
|
||||||
|
A SyncProvider encountered a permanent problem, where a retry will not be successful.
|
||||||
|
"""
|
||||||
|
log_action_type = "pretix.event.order.data_sync.failed.permanent"
|
||||||
|
|
||||||
|
|
||||||
|
class SyncConfigError(UnrecoverableSyncError):
|
||||||
|
"""
|
||||||
|
A SyncProvider is misconfigured in a way where a retry without configuration change will
|
||||||
|
not be successful.
|
||||||
|
"""
|
||||||
|
log_action_type = "pretix.event.order.data_sync.failed.config"
|
||||||
|
|
||||||
|
|
||||||
|
class RecoverableSyncError(BaseSyncError):
|
||||||
|
"""
|
||||||
|
A SyncProvider has encountered a temporary problem, and the sync should be retried
|
||||||
|
at a later time.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
StaticMapping = namedtuple('StaticMapping', ('pk', 'pretix_model', 'external_object_type', 'pretix_id_field', 'external_id_field', 'property_mapping'))
|
StaticMapping = namedtuple('StaticMapping', ('pk', 'pretix_model', 'external_object_type', 'pretix_id_field', 'external_id_field', 'property_mapping'))
|
||||||
|
|
||||||
|
|
||||||
@@ -180,35 +203,40 @@ class OutboundSyncProvider:
|
|||||||
for sq in queued_orders:
|
for sq in queued_orders:
|
||||||
try:
|
try:
|
||||||
mapped_objects = self.sync_order(sq.order)
|
mapped_objects = self.sync_order(sq.order)
|
||||||
except SyncConfigError as e:
|
except UnrecoverableSyncError as e:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"Could not sync order {sq.order.code} to {type(self).__name__} (config error)",
|
f"Could not sync order {sq.order.code} to {type(self).__name__}",
|
||||||
exc_info=True,
|
exc_info=True,
|
||||||
)
|
)
|
||||||
sq.order.log_action("pretix.event.order.data_sync.failed", {
|
sq.order.log_action(e.log_action_type, {
|
||||||
"provider": self.identifier,
|
"provider": self.identifier,
|
||||||
"error": e.messages,
|
"error": e.messages,
|
||||||
"full_message": e.full_message,
|
"full_message": e.full_message,
|
||||||
})
|
})
|
||||||
sq.delete()
|
sq.delete()
|
||||||
except Exception as e:
|
except RecoverableSyncError as e:
|
||||||
# TODO: different handling per Exception, or even per HTTP response code?
|
|
||||||
# otherwise, SyncProviders should always throw SyncConfigError in non-recoverable situations
|
|
||||||
sq.failed_attempts += 1
|
sq.failed_attempts += 1
|
||||||
sq.not_before = self.next_retry_date(sq)
|
sq.not_before = self.next_retry_date(sq)
|
||||||
logger.exception(
|
logger.info(
|
||||||
f"Could not sync order {sq.order.code} to {type(self).__name__} (transient error, attempt #{sq.failed_attempts})"
|
f"Could not sync order {sq.order.code} to {type(self).__name__} (transient error, attempt #{sq.failed_attempts})",
|
||||||
|
exc_info=True,
|
||||||
)
|
)
|
||||||
if sq.failed_attempts >= self.max_attempts:
|
if sq.failed_attempts >= self.max_attempts:
|
||||||
sentry_sdk.capture_exception(e)
|
sentry_sdk.capture_exception(e)
|
||||||
sq.order.log_action("pretix.event.order.data_sync.failed", {
|
sq.order.log_action("pretix.event.order.data_sync.failed.exceeded", {
|
||||||
"provider": self.identifier,
|
"provider": self.identifier,
|
||||||
"error": [_("Maximum number of retries exceeded.")],
|
"error": e.messages,
|
||||||
"full_message": str(e),
|
"full_message": e.full_message,
|
||||||
})
|
})
|
||||||
sq.delete()
|
sq.delete()
|
||||||
else:
|
else:
|
||||||
sq.save()
|
sq.save()
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(
|
||||||
|
f"Could not sync order {sq.order.code} to {type(self).__name__} (unhandled exception)"
|
||||||
|
)
|
||||||
|
sentry_sdk.capture_exception(e)
|
||||||
|
sq.delete()
|
||||||
else:
|
else:
|
||||||
sq.order.log_action("pretix.event.order.data_sync.success", {
|
sq.order.log_action("pretix.event.order.data_sync.success", {
|
||||||
"provider": self.identifier,
|
"provider": self.identifier,
|
||||||
|
|||||||
@@ -443,7 +443,9 @@ class OrderDataSyncLogEntryType(OrderLogEntryType):
|
|||||||
|
|
||||||
|
|
||||||
@log_entry_types.new_from_dict({
|
@log_entry_types.new_from_dict({
|
||||||
"pretix.event.order.data_sync.failed": _("Error while transferring data to {provider}:"),
|
"pretix.event.order.data_sync.failed.config": _("Transferring data to {provider} failed due to invalid configuration:"),
|
||||||
|
"pretix.event.order.data_sync.failed.exceeded": _("Maximum number of retries exceeded while transferring data to {provider}:"),
|
||||||
|
"pretix.event.order.data_sync.failed.permanent": _("Error while transferring data to {provider}:"),
|
||||||
})
|
})
|
||||||
class OrderDataSyncErrorLogEntryType(OrderLogEntryType):
|
class OrderDataSyncErrorLogEntryType(OrderLogEntryType):
|
||||||
def display(self, logentry, data):
|
def display(self, logentry, data):
|
||||||
|
|||||||
Reference in New Issue
Block a user