Error handling

All domain-specific exceptions declared by Upref inherit UprefError. Applications can catch the base class at a boundary or catch a specific error where recovery differs. Standard exceptions used for programmer errors are listed separately below.

Exception hierarchy

UprefError
|-- ConfigPathError (also ValueError)
|-- ConfigFormatError
|-- ConfigReadError
|-- ConfigWriteError
|-- MigrationError
|-- PromptCancelled
`-- PromptUnavailableError

Exception

Typical cause

ConfigPathError

An unsafe application name or filename, a relative explicit directory, or a path that escapes its directory.

ConfigFormatError

Invalid YAML or UTF-8, a non-mapping root, a non-string key, a cyclic value, or an unsupported Python value.

ConfigReadError

A filesystem error while opening or reading configuration.

ConfigWriteError

A filesystem error while creating, replacing, or deleting a file.

MigrationError

A missing legacy file, identical source and target, an existing target without overwrite=True, or a failure while saving migrated data.

PromptCancelled

The user cancelled, interrupted, or ended an interactive prompt.

PromptUnavailableError

The requested GUI dependency is absent or cannot initialize.

Malformed YAML errors include the path and, when PyYAML provides it, the line and column. Read and write messages also include the relevant path. The original Python, operating-system, or YAML exception is preserved as the exception cause.

Recovering by operation

A typical application distinguishes a missing file—which load handles as an empty mapping—from a present but invalid file, which should be reported and left untouched:

from upref import (
    ConfigFormatError,
    ConfigReadError,
    ConfigStore,
    ConfigWriteError,
)

store = ConfigStore("my-app")

try:
    config = store.load(defaults={"theme": "dark"})
except ConfigFormatError as error:
    # Ask the user to repair or deliberately replace the malformed file.
    print(f"Invalid configuration: {error}")
except ConfigReadError as error:
    print(f"Cannot read configuration: {error}")
else:
    try:
        store.save(config)
    except ConfigWriteError as error:
        print(f"Cannot save configuration: {error}")

Do not automatically overwrite malformed configuration unless that is an explicit application policy. The invalid file may contain recoverable user data.

Programmer errors

Some API misuse raises standard exceptions rather than an UprefError:

  • an unknown collection mode or string interface raises ValueError;

  • a non-string schema key, a schema value that is not Field, or an object that does not implement Prompter raises TypeError;

  • a parser or validator ValueError is treated as correctable input and causes another prompt;

  • asking through or reporting an error with a closed upref.gui.GuiPrompter raises RuntimeError;

  • unexpected exceptions from application parsers, validators, or custom prompters propagate unchanged.

Catch exceptions only at a level that can make a meaningful recovery choice. In particular, catching UprefError around an entire application may hide whether user input, file content, or filesystem access needs attention.