Skip to main content

Error Handling

Errors mapped from the GooseFS SDK core inherit from GoosefsError, which itself inherits from Exception. Local Python API validation and safety guards may instead raise built-in exceptions such as ValueError or RuntimeError.

Exception Hierarchy

Exception
└── GoosefsError
├── NotFound # path does not exist
├── AlreadyExists # rename to existing destination
├── PermissionDenied # ACL / auth failure
├── InvalidArgument # malformed path, bad offset, etc.
├── FileIncomplete # file still being written
├── DirectoryNotEmpty # non-recursive delete on non-empty dir
├── IsADirectory # tried to read a directory as a file
├── AuthenticationFailed # SASL handshake failed
├── NoWorkerAvailable # no healthy worker for the block
├── MasterUnavailable # all master replicas unreachable
├── ConfigError # invalid configuration
├── RpcError # gRPC transport / protocol error
└── IoError # local I/O (block read/write)

Usage

from goosefs import AsyncGoosefs, Config
from goosefs.exceptions import GoosefsError, NotFound, PermissionDenied

async with await AsyncGoosefs.connect(Config("127.0.0.1:9200")) as fs:
try:
status = await fs.get_status("/data/missing")
except NotFound:
print("path does not exist")
except PermissionDenied as e:
print(f"access denied: {e}")
except GoosefsError as e:
# Catch-all for any other SDK error
print(f"goosefs error: {e}")

Mapping Reference

The Rust binding maps every goosefs_sdk::error::Error variant to a specific Python exception — there is no fall-through to a generic catch-all:

SDK Error variantPython exception
NotFoundNotFound
AlreadyExistsAlreadyExists
PermissionDeniedPermissionDenied
InvalidArgumentInvalidArgument
InvalidPathInvalidArgument
FileIncompleteFileIncomplete
DirectoryNotEmptyDirectoryNotEmpty
OpenDirectoryIsADirectory
AuthenticationFailedAuthenticationFailed
NoWorkerAvailableNoWorkerAvailable
MasterUnavailableMasterUnavailable
ConfigErrorConfigError
GrpcErrorRpcError
TransportErrorRpcError
BlockIoErrorIoError
MissingFieldGoosefsError (with descriptive message)
InternalGoosefsError (with descriptive message)

Common Patterns

Retry on transient errors

import asyncio
from goosefs.exceptions import RpcError, MasterUnavailable, NoWorkerAvailable

TRANSIENT = (RpcError, MasterUnavailable, NoWorkerAvailable)

for attempt in range(3):
try:
return await fs.read_file(path)
except TRANSIENT:
if attempt == 2:
raise
await asyncio.sleep(2 ** attempt)

Distinguish "not found" from other errors

try:
status = await fs.get_status(path)
except NotFound:
return None # expected — path may not exist yet