Documentation Index
Fetch the complete documentation index at: https://docs.declaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
import (
"errors"
"github.com/declaw-ai/declaw-go"
)
All SDK errors embed *SandboxError, which implements the error interface. Use errors.As to match specific error types, or check the base *SandboxError to catch any Declaw error.
Error hierarchy
error
└── *SandboxError
├── *TimeoutError
├── *NotFoundError
├── *AuthenticationError
├── *InvalidArgumentError
├── *NotEnoughSpaceError
├── *FileUploadError
├── *GitAuthError
├── *GitUpstreamError
├── *CommandExitError
├── *InsufficientBalanceError
├── *RateLimitError
├── *TemplateError
└── *BuildError
SandboxError
Base error type for all Declaw errors.
type SandboxError struct {
Message string
SandboxID string
StatusCode int
}
| Field | Type | Description |
|---|
Message | string | Human-readable error description |
SandboxID | string | The sandbox ID involved, when available |
StatusCode | int | HTTP status code from the API response |
NotFoundError
Returned when a sandbox or resource does not exist (HTTP 404).
sbx, err := declaw.Connect(ctx, "nonexistent-id")
if err != nil {
var nfe *declaw.NotFoundError
if errors.As(err, &nfe) {
fmt.Println("Sandbox not found:", nfe.Message)
}
}
AuthenticationError
Returned when the API key is missing or invalid (HTTP 401/403).
sbx, err := declaw.Create(ctx)
if err != nil {
var ae *declaw.AuthenticationError
if errors.As(err, &ae) {
fmt.Println("Invalid API key")
}
}
InsufficientBalanceError
Returned when the account has insufficient balance (HTTP 402).
sbx, err := declaw.Create(ctx)
if err != nil {
var ibe *declaw.InsufficientBalanceError
if errors.As(err, &ibe) {
fmt.Println("Top up required:", ibe.Message)
}
}
RateLimitError
Returned when the API rate limit is exceeded (HTTP 429). Inspect RetryAfter and back off before retrying.
sbx, err := declaw.Create(ctx)
if err != nil {
var rle *declaw.RateLimitError
if errors.As(err, &rle) {
fmt.Printf("Rate limited. Retry after %v\n", rle.RetryAfter)
time.Sleep(rle.RetryAfter)
}
}
| Field | Type | Description |
|---|
RetryAfter | time.Duration | How long to wait before retrying |
Limit | int | Rate limit ceiling |
Remaining | int | Requests remaining in current window |
CommandExitError
Returned when a command exits with a non-zero exit code. Contains the full stdout, stderr, and exit code. Note that Run() returns both the *CommandResult and the error, so you can inspect output even on failure.
result, err := sbx.Commands.Run(ctx, "python3 -c \"raise ValueError('oops')\"")
if err != nil {
var exitErr *declaw.CommandExitError
if errors.As(err, &exitErr) {
fmt.Printf("Exit code: %d\n", exitErr.ExitCode)
fmt.Printf("Stderr: %s\n", exitErr.Stderr)
}
}
| Field | Type | Description |
|---|
ExitCode | int | The process exit code |
Stdout | string | Captured standard output |
Stderr | string | Captured standard error |
TimeoutError
Returned when an operation exceeds its configured timeout (HTTP 408).
InvalidArgumentError
Returned when invalid arguments are passed to an API call (HTTP 422).
NotEnoughSpaceError
Returned when the sandbox filesystem is full (HTTP 507).
TemplateError / BuildError
Returned on template build or retrieval errors.
Catching all Declaw errors
sbx, err := declaw.Create(ctx)
if err != nil {
var se *declaw.SandboxError
if errors.As(err, &se) {
fmt.Printf("Declaw error (HTTP %d): %s\n", se.StatusCode, se.Message)
if se.SandboxID != "" {
fmt.Println("Sandbox ID:", se.SandboxID)
}
}
}
Retry patterns
Simple retry with backoff
func runWithRetry(ctx context.Context, sbx *declaw.Sandbox, cmd string, retries int) (string, error) {
delay := time.Second
for attempt := 0; attempt < retries; attempt++ {
result, err := sbx.Commands.Run(ctx, cmd,
declaw.WithRunTimeout(30*time.Second),
)
if err == nil {
return result.Stdout, nil
}
// Don't retry deterministic failures
var exitErr *declaw.CommandExitError
if errors.As(err, &exitErr) {
return "", err // non-zero exit won't improve on retry
}
var ae *declaw.AuthenticationError
if errors.As(err, &ae) {
return "", err
}
var nfe *declaw.NotFoundError
if errors.As(err, &nfe) {
return "", err
}
if attempt < retries-1 {
time.Sleep(delay)
delay *= 2
}
}
return "", fmt.Errorf("command failed after %d retries", retries)
}
Handle rate limits
func createWithRateLimit(ctx context.Context) (*declaw.Sandbox, error) {
for {
sbx, err := declaw.Create(ctx, declaw.WithTimeout(300))
if err == nil {
return sbx, nil
}
var rle *declaw.RateLimitError
if errors.As(err, &rle) && rle.RetryAfter > 0 {
time.Sleep(rle.RetryAfter)
continue
}
return nil, err
}
}
Handle non-zero exit codes
result, err := sbx.Commands.Run(ctx, "python3 risky_script.py")
if err != nil {
var exitErr *declaw.CommandExitError
if errors.As(err, &exitErr) {
fmt.Printf("Script failed (exit %d)\n", exitErr.ExitCode)
fmt.Printf("Stderr: %s\n", exitErr.Stderr)
// result is still available
fmt.Printf("Stdout: %s\n", result.Stdout)
} else {
log.Fatal(err) // network or other error
}
}