Error Handling
Best practices for handling errors across all SDKs.
Error Types
All SDKs provide typed errors:
| Error Type | Description |
|---|---|
IOFError | Base API error |
ValidationError | Invalid request data |
AuthenticationError | Invalid credentials |
RateLimitError | Rate limit exceeded |
NetworkError | Connection issues |
TypeScript/JavaScript
typescript
import { IslamicOpenFinance, IOFError, ValidationError } from "@iof/sdk";
try {
const contract = await iof.contracts.create({ ... });
} catch (error) {
if (error instanceof ValidationError) {
console.error("Validation failed:");
error.details.forEach(d => {
console.error(` ${d.field}: ${d.message}`);
});
} else if (error instanceof IOFError) {
console.error(`API error: ${error.code} - ${error.message}`);
} else {
console.error("Unexpected error:", error);
}
}Python
python
from iof import IslamicOpenFinance, IOFError, ValidationError
try:
contract = iof.contracts.create(...)
except ValidationError as e:
print("Validation failed:")
for detail in e.details:
print(f" {detail['field']}: {detail['message']}")
except IOFError as e:
print(f"API error: {e.code} - {e.message}")
except Exception as e:
print(f"Unexpected error: {e}")Go
go
contract, err := client.Contracts.Create(ctx, params)
if err != nil {
var iofErr *iof.Error
if errors.As(err, &iofErr) {
fmt.Printf("API error: %s - %s\n", iofErr.Code, iofErr.Message)
if iofErr.Code == "VALIDATION_ERROR" {
for _, detail := range iofErr.Details {
fmt.Printf(" %s: %s\n", detail.Field, detail.Message)
}
}
} else {
fmt.Printf("Unexpected error: %v\n", err)
}
}Java
java
try {
Contract contract = client.contracts().create(params);
} catch (ValidationException e) {
System.err.println("Validation failed:");
for (var detail : e.getDetails()) {
System.err.println(" " + detail.getField() + ": " + detail.getMessage());
}
} catch (IOFException e) {
System.err.println("API error: " + e.getCode() + " - " + e.getMessage());
} catch (Exception e) {
System.err.println("Unexpected error: " + e.getMessage());
}Retry Strategies
Exponential Backoff
typescript
async function withRetry<T>(
fn: () => Promise<T>,
maxRetries = 3
): Promise<T> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (error instanceof RateLimitError) {
const delay = Math.pow(2, attempt) * 1000;
await sleep(delay);
continue;
}
throw error;
}
}
throw new Error("Max retries exceeded");
}
// Usage
const contract = await withRetry(() =>
iof.contracts.create({ ... })
);Idempotency Keys
typescript
const contract = await iof.contracts.create(
{ ... },
{ idempotencyKey: "unique-request-id" }
);Best Practices
- Always handle errors - Don't let errors fail silently
- Log request IDs - Include
requestIdin error logs - Use typed errors - Check error types for specific handling
- Implement retries - Retry transient errors with backoff
- Use idempotency - Prevent duplicate operations
Next Steps
- Pagination - Handle large datasets
- Webhooks - Event handling