Source code for calendaring_sync.error
# SPDX-FileCopyrightText: 2026 calendaring-sync contributors
# SPDX-License-Identifier: AGPL-3.0-or-later
"""calendaring-sync's error hierarchy.
Every error the library raises on purpose derives from
:class:`CalendaringSyncError`. A call with an argument that can never be
valid, such as a negative cursor, raises :class:`ValueError` instead.
"""
[docs]
class CalendaringSyncError(Exception):
"""Base for every calendaring-sync error."""
[docs]
class StaleChangeSetError(CalendaringSyncError):
"""A :term:`change set` was fetched from a token the :term:`scope` no longer has.
Another process ingested first, or started another listing of the same
scope. The changes it fetched are already outdated, so the adapter
fetches again from the scope's current token.
"""
[docs]
class TrimmedFeedError(CalendaringSyncError):
"""A :term:`cursor` is older than the oldest :term:`change feed` entry kept.
The entries after the cursor were trimmed, so they can't be read. Read
the scope's records again, and continue from
:meth:`~calendaring_sync.replica.Replica.feed_head`.
"""
[docs]
class UnknownScopeError(CalendaringSyncError):
"""The :term:`store` has no :term:`scope` with this id."""
[docs]
class UnknownRecordError(CalendaringSyncError):
"""The :term:`store` has no :term:`record` with this :term:`local key`."""
[docs]
class DuplicateObjectError(CalendaringSyncError):
"""Another :term:`record` in the :term:`scope` already has this :term:`object id`."""
[docs]
class ScopeMismatchError(CalendaringSyncError):
"""A :term:`session` was opened with a media type the :term:`scope` doesn't have.
The stored content is in the scope's media type, so it can't be reused.
Drop the scope and sync it again.
"""
[docs]
class SessionError(CalendaringSyncError):
"""A :term:`session` was used out of order.
For example a second session on a scope that already has one open, an
ingest after the session's last page, or a reset while a session is open.
"""
[docs]
class TransactionError(CalendaringSyncError):
"""A :term:`store` transaction was used the wrong way.
Raised for a transaction opened while the thread already has one, and
for closing the store inside a transaction. Its subclasses cover an
operation outside a transaction and a write inside a read.
"""
[docs]
class TransactionRequiredError(TransactionError):
"""A :term:`store` operation ran outside a transaction."""
[docs]
class TransactionPermissionError(TransactionError):
"""A :term:`store` operation that writes ran in a transaction opened with ``write=False``."""
[docs]
class StoreError(CalendaringSyncError):
"""The :term:`store` couldn't read or write its data, such as a file that isn't a store."""
[docs]
class StoreBusyError(StoreError):
"""Another process kept the :term:`store` busy for longer than the store waits.
Nothing was changed. Try again later.
"""
[docs]
class StoreVersionError(StoreError):
"""The store was written by a newer calendaring-sync, with a schema this one can't read."""
[docs]
class UnexpectedStoreError(CalendaringSyncError):
"""A :term:`store` failed in a way it doesn't expect, which is a bug in it or its caller.
It isn't a :class:`StoreError`, so code that retries on a store error
doesn't retry a bug. The original exception is its ``__cause__``.
"""