synology_apm_repo.sdk.errors module

Exception hierarchy for synology-apm-repo-sdk.

Every exception carries two optional pieces of support/forensics context:

  • ref: which node/file the error refers to — always a plain string: a store-relative path, a file_map path, or any other locator meaningful to a human reading the error. Callers holding a NodeRef pass str(node_ref); this module deliberately does not import that type, to avoid a dependency from the lowest layer (errors, used everywhere) onto the highest one (units).

  • spec: a pointer into FORMAT-SPEC.md (e.g. "FORMAT-SPEC.md: SizeStore") explaining why this is an error, not just that it is one. This is a support/forensics tool, not a general-purpose library — errors that name the offending node and the governing spec section are worth the extra keyword argument at every raise site.

Deliberately NOT named KeyError anywhere in this hierarchy — that name shadows the built-in and would be silently swallowed by unrelated except KeyError blocks.

Argument/programmer-error validation (a negative offset or length, an out-of-range index) raises stdlib ValueError/IndexError directly, never wrapped in this hierarchy — this hierarchy is reserved for on-disk data problems, not caller mistakes.

exception synology_apm_repo.sdk.errors.ApmRepoError(message, *, ref=None, spec=None)

Bases: Exception

Base of all errors raised by synology-apm-repo-sdk.

property safe_message: str

This error’s message alone, without the [ref=...]/ [spec=...] tags str(exc) appends — for a presentation layer’s default, non-verbose rendering. Strips only that structured suffix, not every occurrence of the same value a raise site’s own message text may separately mention. str(exc) itself is unchanged and keeps carrying the full detail (internal call sites that store str(exc) for later diagnostic display, e.g. units/device_disk_fs.py’s per-disk failure reasons, rely on that).

exception synology_apm_repo.sdk.errors.FormatError(message, *, ref=None, spec=None)

Bases: ApmRepoError

The bytes at ref do not match the on-disk format they were expected to have (magic mismatch, CRC mismatch, unsupported header version, truncated file, …).

exception synology_apm_repo.sdk.errors.DataCorruptError(message, *, ref=None, spec=None)

Bases: FormatError

A CRC32 (or similar) integrity check failed: the magic matched but the payload did not survive intact.

exception synology_apm_repo.sdk.errors.UnsupportedVersionError(message, *, ref=None, spec=None)

Bases: FormatError

The on-disk major/minor version is newer than this SDK understands.

exception synology_apm_repo.sdk.errors.ChunkCompactedError(message, *, ref=None, spec=None)

Bases: FormatError

SizeStore reports CompressType.COMPACTED for this chunk — the data was reclaimed by the write-side compactor and can no longer be read (FORMAT-SPEC.md: SizeStore).

exception synology_apm_repo.sdk.errors.KeyMaterialError(message, *, ref=None, spec=None)

Bases: ApmRepoError

The key string itself (<userKeyID>@<base64(userKey)>) is malformed, or does not match this repository’s wrapped VaultKey.

exception synology_apm_repo.sdk.errors.KeyRequiredError(message, *, ref=None, spec=None)

Bases: KeyMaterialError

The repository is encrypted (some .buk has mode bit 0x80 set, or a copy_meta_file entry starts with the aHlT magic) but no key was supplied.

exception synology_apm_repo.sdk.errors.KeyMismatchError(message, *, ref=None, spec=None)

Bases: KeyMaterialError

The AES-256-GCM tag check, or the chunk-fingerprint verification, failed for the supplied key (FORMAT-SPEC.md: chunk-pool-encryption/vaultkey-custody).

exception synology_apm_repo.sdk.errors.NotFoundError(message, *, ref=None, spec=None)

Bases: ApmRepoError

The referenced path / node / version / object does not exist in this repository — as opposed to existing but being unreadable.

exception synology_apm_repo.sdk.errors.ContentUnavailableError(message, *, ref=None, spec=None)

Bases: ApmRepoError

This node’s metadata was found, but its real content is not available to read — either because the guest OS itself only held a placeholder for it at backup time (e.g. a cloud-sync client’s local-storage-optimization eviction, such as iCloud Drive or Windows OneDrive Files-On-Demand), never actual data, or because the real on-disk bytes exist but this SDK has no key material to make sense of them (e.g. an NTFS EFS-encrypted file). Distinct from DataCorruptError: nothing here asserts the on-disk bytes are damaged, only that this SDK could not obtain real content for them. Deliberately not a NotFoundError subclass: callers that catch NotFoundError to treat an optional item as absent-and-skippable must not silently swallow this instead.

exception synology_apm_repo.sdk.errors.PermissionDeniedError(message, *, ref=None, spec=None)

Bases: ApmRepoError

The referenced path / node exists but the OS or backend denied the access needed to read or list it (permission bits, ACL, or an unauthorized credential) — as opposed to not existing at all (see NotFoundError). Deliberately not a NotFoundError subclass: several call sites elsewhere in this SDK catch NotFoundError to treat an optional item as absent-and-skippable, and a permission failure must keep propagating through those instead of being silently swallowed as “doesn’t exist”.

exception synology_apm_repo.sdk.errors.UnsupportedDataFormatError(message, *, ref=None, spec=None)

Bases: ApmRepoError

The content exists but this version of the SDK deliberately refuses to interpret it (e.g. a CBT merge chain) rather than risk emitting silently-wrong bytes.

exception synology_apm_repo.sdk.errors.ProfileNotFoundError(message, *, ref=None, spec=None)

Bases: NotFoundError

The named S3/Azure/SMB connection profile does not exist in profiles.json.

exception synology_apm_repo.sdk.errors.ProfileConfigCorruptError(message, *, ref=None, spec=None)

Bases: DataCorruptError

profiles.json failed to parse, or failed schema validation (bad schema_version, unknown kind, missing/malformed field) — the same “matched the outer shape but the payload didn’t survive intact” contract DataCorruptError already has, applied to this config file instead of an on-disk repository structure.

exception synology_apm_repo.sdk.errors.ProfileSecretBackendUnavailableError(message, *, ref=None, spec=None)

Bases: ApmRepoError

No usable OS keyring backend is available to store/retrieve a profile’s secret fields — either the keyring package failed to import (a broken/partial install; it’s a required dependency, so this should not happen in a well-formed environment), or it imported fine but resolved no real backend (e.g. headless Linux with no Secret Service/dbus). Deliberately not a KeyMaterialError subclass — that hierarchy is about a dedup repository’s own encryption key, an unrelated “key”.