Error Handling Reference
This page documents the error types and handling patterns for the Autonomi Client API.
Error Types
ChunkError
Errors related to chunk operations.
class ChunkError extends Error {
static NotFound: typeof ChunkError;
static InvalidSize: typeof ChunkError;
static NetworkError: typeof ChunkError;
static StorageFull: typeof ChunkError;
}
try {
const chunk = await client.getChunk(address);
} catch (error) {
if (error instanceof ChunkError.NotFound) {
// Handle missing chunk
} else if (error instanceof ChunkError.NetworkError) {
// Handle network issues
}
}
class ChunkError(Exception):
class NotFound(ChunkError): pass
class InvalidSize(ChunkError): pass
class NetworkError(ChunkError): pass
class StorageFull(ChunkError): pass
try:
chunk = client.get_chunk(address)
except ChunkError.NotFound:
# Handle missing chunk
pass
except ChunkError.NetworkError as e:
# Handle network issues
pass
pub enum ChunkError {
NotFound,
InvalidSize,
NetworkError(NetworkError),
StorageFull,
}
match client.get_chunk(address).await {
Ok(chunk) => { /* Process chunk */ }
Err(ChunkError::NotFound) => { /* Handle missing chunk */ }
Err(ChunkError::NetworkError(e)) => { /* Handle network issues */ }
Err(e) => { /* Handle other errors */ }
}
PointerError
Errors related to pointer operations.
class PointerError extends Error {
static NotFound: typeof PointerError;
static VersionConflict: typeof PointerError;
static InvalidTarget: typeof PointerError;
}
try {
await client.updatePointer(address, newTarget);
} catch (error) {
if (error instanceof PointerError.VersionConflict) {
// Handle version conflict
}
}
Error Handling Patterns
Retry Logic
For transient errors like network issues:
async function withRetry<T>(
operation: () => Promise<T>,
maxRetries = 3,
delay = 1000
): Promise<T> {
let lastError: Error;
for (let i = 0; i < maxRetries; i++) {
try {
return await operation();
} catch (error) {
if (error instanceof ChunkError.NetworkError) {
lastError = error;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
throw lastError;
}
// Usage
const chunk = await withRetry(() => client.getChunk(address));
async def with_retry(operation, max_retries=3, delay=1.0):
last_error = None
for i in range(max_retries):
try:
return await operation()
except ChunkError.NetworkError as e:
last_error = e
await asyncio.sleep(delay)
continue
except Exception as e:
raise e
raise last_error
# Usage
chunk = await with_retry(lambda: client.get_chunk(address))
async fn with_retry<F, T, E>(
operation: F,
max_retries: u32,
delay: Duration
) -> Result<T, E>
where
F: Fn() -> Future<Output = Result<T, E>>,
E: From<ChunkError>,
{
let mut last_error = None;
for_ in 0..max_retries {
match operation().await {
Ok(result) => return Ok(result),
Err(e) => {
if let Some(ChunkError::NetworkError(_)) = e.downcast_ref() {
last_error = Some(e);
tokio::time::sleep(delay).await;
continue;
}
return Err(e);
}
}
}
Err(last_error.unwrap())
}
// Usage
let chunk = with_retry(|| client.get_chunk(address), 3, Duration::from_secs(1)).await?;
Error Recovery
For handling version conflicts in pointers:
async function updatePointerSafely(
client: Client,
address: Address,
newTarget: Address
): Promise<void> {
while (true) {
try {
await client.updatePointer(address, newTarget);
break;
} catch (error) {
if (error instanceof PointerError.VersionConflict) {
const current = await client.resolvePointer(address);
if (current.equals(newTarget)) break;
continue;
}
throw error;
}
}
}
async fn update_pointer_safely(
client: &Client,
address: Address,
new_target: Address
) -> Result<()> {
loop {
match client.update_pointer(address, new_target).await {
Ok(_) => break Ok(()),
Err(PointerError::VersionConflict) => {
let current = client.resolve_pointer(address).await?;
if current == new_target {
break Ok(());
}
continue;
}
Err(e) => break Err(e),
}
}
}