Skip to content

Exceptions

obspec.exceptions

Common exceptions.

Users writing generic code with obspec may wish to catch common exceptions. For example, a user might wish to perform a head request but allow for the case where the object does not exist.

Common exceptions pose a challenge for obspec. In general obspec strives to use structural subtyping (protocols) rather than nominal subtyping (subclassing). This is because protocols allow for implementations to have no knowledge of or dependency on a shared base library (obspec) while still being able to use the same interface.

However, structural subtyping does not work for exceptions: when you use except Exception, that uses an isinstance check under the hood.

As a workaround, we define well-known names for exceptions and expect external implementations to use the same names.

Obspec users

Use the map_exception function in this module to convert from an implementation-defined exception to an obspec-defined exception.

from obspec import Head
from obspec.exceptions import NotFoundError, map_exception


def check_if_exists(client: Head, path: str) -> bool:
    """Check if a file exists at the given location.

    Returns True if the file exists, False otherwise.
    """
    try:
        client.head(path)
    except Exception as e:
        if isinstance(map_exception(e), NotFoundError):
            return False

        raise

    return True

Note

If you don't care about catching exceptions, you can ignore this module entirely.

Obspec implementors

Create your own exceptions but ensure you use the same names for your own exceptions as defined in this module.

You may also have other exceptions that are not defined here, but any exceptions that logically fall under the purview of the exceptions defined here should your exceptions with the same name.

ExceptionType module-attribute

ExceptionType = TypeVar('ExceptionType', bound=Exception)

Type variable for an exception type, bound to Exception.

AlreadyExistsError

Bases: BaseError

Error when the object already exists.

BaseError

Bases: Exception

The base obspec exception from which all other errors subclass.

InvalidPathError

Bases: BaseError

Error for invalid path.

NotFoundError

Bases: FileNotFoundError, BaseError

Error when the object is not found at given location.

NotImplementedError

Bases: BaseError, NotImplementedError

Error when an operation is not implemented.

Subclasses from the built-in NotImplementedError.

NotModifiedError

Bases: BaseError

Error when the object at the location isn't modified.

NotSupportedError

Bases: BaseError

Error when the attempted operation is not supported.

PermissionDeniedError

Bases: BaseError

Error when the used credentials don't have enough permission to perform the requested operation.

PreconditionError

Bases: BaseError

Error when the required conditions failed for the operation.

UnauthenticatedError

Bases: BaseError

Error when the used credentials lack valid authentication.

map_exception

map_exception(exception: ExceptionType) -> ExceptionType | BaseError

Map an implementation-defined exception to an obspec-defined exception by name.

This will use the name of the exception class to find a corresponding obspec-defined exception class. If no mapping is found, the original exception is returned.