ResilientLang docsDeveloper documentation (draft, product name is a placeholder)

SDK error handling

All three SDKs (overview; not merged and not published when this page was written) raise one API error type that carries the fields of the problem answer described in Errors.

FieldPythonPHPGoMeaning
statuse.status$e->status()ae.StatusHTTP status
codee.code$e->problemCode()ae.CodeThe problem type without urn:resilientlang:problem:, for example quota-exhausted
field errorse.errors$e->errors()ae.ErrorsPer-field messages on a 400 or 422
import issuese.issues$e->issues()ae.IssuesThe issues of a rejected import
extra memberse.extra$e->extra()ae.ExtraProblem members such as limit, used, resetsOn on a 402
retry delaye.retry_after_seconds$e->retryAfterSeconds()ae.RetryAfter (a duration, zero when absent)From Retry-After
hinte.hint$e->hint()ae.Hint()Plain-language text for 402, 403 and 503
try:
    client.translate(site["id"])
except rl.ApiError as e:
    print(e.status, e.code, e.hint)
except rl.NetworkError:
    ...   # no response after the retries; the message never contains the key
try { $client->translate($site['id']); }
catch (\ResilientLang\ApiException $e) { echo $e->status(), ' ', $e->problemCode(), ' ', $e->hint(); }
catch (\ResilientLang\NetworkException $e) { /* no response after the retries */ }
var ae *rl.APIError
if errors.As(err, &ae) { fmt.Println(ae.Status, ae.Code, ae.Hint()) }   // also ae.IsPlanLimit(), ae.IsPermissionError(), ae.IsGateUnavailable()
var ne *rl.NetworkError   // no response after the retries

What the hints cover#

Network failures are a separate error type and carry no response. Other errors derive from one base type per SDK: waiting for a job that is still running (WaitTimeoutError), a manifest that fails verification (ManifestError) and a bad webhook signature (WebhookSignatureError), each named slightly differently per language. The SDKs already retry 429 and, for safe requests, 502, 503 and 504; see the overview for the rules, so do not add a second blind retry loop around them.