Skip to main content
Ogni errore dell’API, di rete e locale è di un unico tipo: *squarecloud.APIError. Ispezionalo con errors.As.

APIError

Unwrap() restituisce la causa (l’errore di trasporto, di decodifica o del context) per NETWORK_ERROR, TIMEOUT e JSON non valido, altrimenti nil. Error() produce squarecloud: <METHOD> <path>: HTTP <status> <CODE>: <message>, senza HTTP <status> quando lo status è 0 e senza : <message> quando è vuoto. Basati sui campi, non su questo testo.

Context annullati e scaduti

Una chiamata il cui ctx viene annullato restituisce un *APIError con NETWORK_ERROR, e una la cui scadenza passa restituisce TIMEOUT, entrambi con status 0. Entrambi fanno l’unwrap all’errore del context:
Alcuni fallimenti non sono *APIError:
  • Realtime.Next restituisce il semplice ctx.Err() quando il suo ctx termina, e io.EOF quando il flusso termina normalmente.
  • I problemi dal lato del chiamante sono errori semplici: un reader di upload nil, un URL di snapshot o un URL base che non può essere analizzato, un input che encoding/json non riesce a codificare e un errore dell’io.Writer passato a DownloadSnapshot.

Codici dell’SDK

Costanti Code*

Code è una semplice string. Il package ha una costante per ogni codice pubblico dell’API, con il nome in stile Go (CodeAppNotFound per APP_NOT_FOUND, CodeInvalidID, CodeDNSFailed, …), più i codici propri dell’SDK elencati sopra. L’elenco dei codici dell’API cresce. Gestisci un codice sconosciuto in base al suo status HTTP:

Errori di qualsiasi chiamata

Codici dell’API per gruppo

APP_NOT_FOUND, DATABASE_NOT_FOUND, WORKSPACE_NOT_FOUND, MEMBER_NOT_FOUND, FILE_NOT_FOUND, SNAPSHOT_NOT_FOUND, REPOSITORY_NOT_FOUND, BRANCH_NOT_FOUND, ROUTE_NOT_FOUND
INVALID_ACCESS_TOKEN, INVALID_AUTORESTART, INVALID_BRANCH_LENGTH, INVALID_CODE, INVALID_CONTENT, INVALID_CONTENT_TYPE, INVALID_DATABASE_TYPE, INVALID_DATABASE_VERSION, INVALID_DESCRIPTION, INVALID_DISPLAY_NAME, INVALID_DOMAIN, INVALID_ENCODING, INVALID_ENV_CONTENT, INVALID_FILE, INVALID_FILENAME, INVALID_FILTER, INVALID_GROUP, INVALID_ID, INVALID_INPUT, INVALID_JSON_BODY, INVALID_MEMORY, INVALID_NAME, INVALID_PARAMETERS, INVALID_PATH, INVALID_RESET_TYPE, INVALID_SCOPE, INVALID_SNAPSHOT_ID, INVALID_SUBDOMAIN, INVALID_TIME_RANGE, INVALID_VERSION_ID, MISSING_PARAMETERS, MISSING_REQUIRED_FIELDS, NO_UPDATE_DATA, VALIDATION_FAILED, VALIDATION_TIMEOUT, ENV_NAME_TOO_LONG, ENV_CONTENT_TOO_LONG, TOO_MANY_ENV_VARS, RESERVED_DOMAIN, CANNOT_SET_SUBDOMAIN, STATIC_APP_ENV_NOT_SUPPORTED
ACCESS_DENIED, MISSING_SCOPE, RESOURCE_NOT_ALLOWED, PERMISSION_DENIED, SCOPE_NOT_GRANTABLE, BLOCKED_PATH, UPGRADE_REQUIRED
RATE_LIMITED, KEEP_CALM, APPLICATIONS_LIMIT_REACHED, WORKSPACE_LIMIT_REACHED, MEMBERS_LIMIT_REACHED, LOAD_BALANCER_LIMIT_REACHED, DAILY_SNAPSHOTS_LIMIT_REACHED, INSUFFICIENT_MEMORY, FILE_TOO_LARGE, PAYLOAD_TOO_LARGE, REALTIME_MAX_CONNECTIONS, REALTIME_MAX_CONNECTIONS_APP, AI_DAILY_LIMIT_REACHED, AI_MAX_CONCURRENT_STREAMS, AI_NO_PLAN_LIMIT_REACHED
CONTAINER_ALREADY_STARTED, CONTAINER_ALREADY_STOPPED, CONTAINER_TEMPORARILY_SUSPENDED, CONTAINER_NOT_FOUND, CONTAINER_INSUFFICIENT_DISK_SPACE, CONTAINER_NETWORK_CONFLICT, ACTION_FAILED, DATABASE_NOT_RUNNING
UPLOAD_BUSY, UPLOAD_FAILED, UPLOAD_ABORTED, STORAGE_UPLOAD_FAILED, COMMIT_FAILED, READ_FAILED, SAVE_FAILED, RENAME_FAILED, DELETE_FAILED, REQUEST_ABORTED, EMPTY_RESPONSE
SNAPSHOT_FAILED, SNAPSHOT_PROCESSING, SNAPSHOT_RESTORE_FAILED, SNAPSHOT_DATABASE_MISMATCH, RESTORE_IN_PROGRESS
GIT_ALREADY_CONFIGURED, GIT_NOT_CONFIGURED, GITHUB_NOT_CONNECTED, REPOSITORY_BRANCH_ALREADY_CONFIGURED, REPOSITORY_NOT_AVAILABLE, REPOSITORY_PERMISSION_REQUIRED, FAILED_TO_FETCH
ANALYTICS_BUSY, UNABLE_TO_FETCH_ANALYTICS, UNABLE_TO_FETCH_ERRORS, UNABLE_TO_FETCH_PERFORMANCE, DNS_FAILED, DOMAIN_ALREADY_EXISTS, NO_CUSTOM_DOMAIN, PURGE_CACHE_FAILED, LOGS_UNAVAILABLE, METRICS_NOT_SUPPORTED
DATABASE_CREATION_FAILED, DATABASE_UNAVAILABLE, RESET_FAILED, WORKSPACE_CREATION_FAILED, APP_ALREADY_IN_WORKSPACE, MEMBER_ALREADY_ADDED, CANNOT_EDIT_OWNER, CANNOT_INVITE_OWNER, CANNOT_LEAVE_OWNER, CONFLICTING_RESOURCES
INTERNAL_SERVER_ERROR, CLUSTER_MAINTENANCE_TRY_LATER, CLUSTER_SELECTION_FAILED, CLUSTER_TIMEOUT, CLUSTER_UNAVAILABLE, AI_UNAVAILABLE
CodeRateLimit (RATE_LIMIT) e CodeRateLimitExceeded (RATE_LIMIT_EXCEEDED) sono ancora esportati, contrassegnati come deprecati: l’API ora risponde RATE_LIMITED (CodeRateLimited) per entrambi.
Gli errori di AI.Chat usano invece i codici minuscoli di OpenAI (access_denied, rate_limit_exceeded, server_overloaded, …), che Code riporta testualmente. Vedi AI.

Retry

L’SDK ripete solo ciò che è sicuro ripetere, fino a WithMaxRetries volte (predefinito 2, quindi fino a 3 tentativi): Non ripete mai:
  • TIMEOUT;
  • qualsiasi 429: RATE_LIMITED può essere un blocco di circa 30 minuti, e nemmeno KEEP_CALM viene ripetuto;
  • gli altri 5xx;
  • gli errori dell’AI.
503 DATABASE_UNAVAILABLE può arrivare dopo che una mutazione è già stata applicata, quindi l’SDK non lo ripete al di fuori di GET. Ripeti tu le tue mutazioni idempotenti, se necessario. Un upload viene ripetuto solo quando il suo body può essere riprodotto: un io.ReaderAt con dimensione nota, come un *os.File (vedi Commit e upload). L’attesa prima del retry n (a partire da 0) è min(8 s, 500 ms · 2^n) · U(0.5, 1): backoff esponenziale con jitter dal 50% al 100%. Imposta WithMaxRetries(0) per disattivare i retry.

Timeout

WithTimeout (30 s) si applica solo quando ctx non ha una scadenza, e una sola scadenza copre l’intera chiamata, compresi i retry e le attese di backoff. Vedi Timeout per le chiamate con una soglia minima di 2 minuti e quelle senza scadenza predefinita. Una scadenza superata restituisce TIMEOUT con status 0, non viene mai ripetuta e fa l’unwrap a context.DeadlineExceeded.

Rate limit

Ogni account ha un limite di richieste ogni 60 secondi, stabilito dal suo piano (valori), e alcune route hanno un limite proprio:
  • 429 RATE_LIMITED: un blocco dell’account, della chiave API o dell’IP, che può durare circa 30 minuti. È anche il limite degli endpoint di rete e di Account.Snapshots.
  • 429 KEEP_CALM: troppe chiamate a una route in poco tempo.
L’SDK non ripete mai un 429. Rallenta e attendi prima di riprovare.