Python · Errors

Errors

import ustorefrom ustore import Error 1.0.0-rc.1 · d6d40961

Every failure raises a subclass of ustore.Error, itself a RuntimeError, and each carries the status the C ABI reported as its status attribute, a ustore.Status member:

transaction = database.transaction(ustore.Watch.KEYS)
try:
    transaction.set(key, value)
    transaction.commit(ustore.Durability.FLUSHED)
except ustore.ConflictError as error:
    assert error.status in (ustore.Status.WRITE_CONFLICT, ustore.Status.READ_CONFLICT)
finally:
    transaction.close()

SUCCESS and DEFERRED raise nothing, and every other member has its own class, which also derives the built-in naming the same fault where one exists:

  • OUT_OF_MEMORY → OutOfMemoryError, a MemoryError
  • READ_ONLY → ReadOnlyError
  • IO → InputOutputError, an OSError
  • DEVICE → DeviceError
  • MALFORMED → MalformedError, a ValueError
  • INTERNAL → InternalError
  • UNINITIALIZED → UninitializedError
  • CONTENDED → ContendedError
  • CANCELLED → CancelledError
  • UNSUPPORTED → UnsupportedError, a NotImplementedError
  • INVALID_ARGUMENT → InvalidArgumentError, a ValueError
  • NOT_FOUND → NotFoundError, a KeyError
  • ALREADY_EXISTS → AlreadyExistsError, a ValueError
  • WRITE_CONFLICT → WriteConflictError, a ConflictError
  • READ_CONFLICT → ReadConflictError, a ConflictError
  • PHANTOM_CONFLICT → PhantomConflictError, a ConflictError
  • CAPACITY_EXHAUSTED → CapacityExhaustedError, an OverflowError

So except KeyError catches a missing collection, and except ConflictError is the one clause a retry loop needs for the three conflicts. A database view_rocksdb opened raises ReadOnlyError from every call that would change it: writes, removes, transactions, collection creates and drops, clears and compactions. A failure the binding catches before the boundary raises the class the engine would have raised for the same fault: a closed database, transaction, snapshot or executor raises UninitializedError, a view of a collection holding another modality raises InvalidArgumentError, and a count of values that disagrees with the count of keys raises InvalidArgumentError too. An argument of the wrong Python type raises TypeError, and a snapshot refuses a write with one.

API

Types

StatusWhat went wrong, valued as ustore_status_t: Error.status and Deferred.status.
__init__.py:85 ↗
class Status(IntEnum)

Values

SUCCESS0
DEFERRED1
OUT_OF_MEMORY2
READ_ONLY6
IO7
DEVICE8
MALFORMED9
INTERNAL10
UNINITIALIZED12
CONTENDED14
CANCELLED15
UNSUPPORTED16
INVALID_ARGUMENT17
NOT_FOUND18
ALREADY_EXISTS19
WRITE_CONFLICT20
READ_CONFLICT21
PHANTOM_CONFLICT22
CAPACITY_EXHAUSTED23
OutOfMemoryErrorAn allocation could not be satisfied.
__init__.py:303 ↗
class OutOfMemoryError(Error, MemoryError)
InvalidArgumentErrorAn argument is null, contradicts another one, or carries a choice the call does not accept, like a collection of another modality.
__init__.py:306 ↗
class InvalidArgumentError(Error, ValueError)
UninitializedErrorThe call needs a handle that was never opened or is closed, or reads a result whose arena a later call rewound.
__init__.py:310 ↗
class UninitializedError(Error)
UnsupportedErrorThe engine or this build does not implement what the call asks for.
__init__.py:314 ↗
class UnsupportedError(Error, NotImplementedError)
InputOutputErrorA file or directory could not be opened, read, written, or closed.
__init__.py:317 ↗
class InputOutputError(Error, OSError)
MalformedErrorStored or supplied data could not be decoded, like a corrupted file or an invalid document.
__init__.py:320 ↗
class MalformedError(Error, ValueError)
NotFoundErrorA collection, a directory, or a document a modification needs does not exist.
__init__.py:323 ↗
class NotFoundError(Error, KeyError)
AlreadyExistsErrorA collection name or a document the call creates is already taken, or a raw medium's first slot is not free.
__init__.py:326 ↗
class AlreadyExistsError(Error, ValueError)
ConflictErrorA concurrent writer touched what this transaction wrote, read or scanned: the one base a retry loop catches.
__init__.py:329 ↗
class ConflictError(Error)
WriteConflictErrorA concurrent writer changed a key this transaction wrote; retry the transaction.
__init__.py:332 ↗
class WriteConflictError(ConflictError)
ReadConflictErrorA concurrent writer changed a key this transaction read; retry the transaction.
__init__.py:335 ↗
class ReadConflictError(ConflictError)
PhantomConflictErrorA concurrent writer inserted into a range this transaction scanned; retry the transaction.
__init__.py:338 ↗
class PhantomConflictError(ConflictError)
CapacityExhaustedErrorA hard design ceiling was reached.
__init__.py:341 ↗
class CapacityExhaustedError(Error, OverflowError)
DeviceErrorA device could not be selected or claimed, or the executor, database and arena of a call live apart.
__init__.py:344 ↗
class DeviceError(Error)
InternalErrorThe engine failed in a way no other status names, which points at a defect.
__init__.py:347 ↗
class InternalError(Error)
ContendedErrorThe call was refused rather than waited for: a full deferred table, an arena serving another call or exporting a buffer, or a transaction serving another call; retry it once that one finishes or the buffer is released.
__init__.py:350 ↗
class ContendedError(Error)
CancelledErrorA progress callback stopped the call, which unwound and published nothing.
__init__.py:354 ↗
class CancelledError(Error)
ReadOnlyErrorThe call would change a database opened read-only, as Database.view_rocksdb opens one.
__init__.py:357 ↗
class ReadOnlyError(Error)
ClassErrorEvery failure the engine reports, one subclass per status shared with the C ABI.1
lib.pyi:297 ↗
class Error(RuntimeError)
statusThe status, such as Status.WRITE_CONFLICT or Status.OUT_OF_MEMORY.
lib.pyi:300 ↗
status: Status