Repository navigation
Errors EN
sungaowei edited this page Oct 16, 2026
·
1 revision
English | 简体中文
Every error the SDK returns implements typesafe.TypeSafeError. Unsuccessful HTTP statuses map onto typed errors, and each typed error unwraps to *APIError, so errors.As finds both the specific and the general form.
| Status | Type | Description |
|---|---|---|
| 400 | *BadRequestError |
Malformed request syntax or unparseable JSON |
| 401 | *AuthenticationError |
Missing, invalid, or expired API key |
| 403 | *PermissionDeniedError |
Insufficient permissions for model or feature |
| 404 | *NotFoundError |
Resource or endpoint not found |
| 413 | *PayloadTooLargeError |
Request body exceeds 32 MiB, or image exceeds 16 MiB |
| 415 | *UnsupportedMediaTypeError |
Unsupported Content-Type or image format (PNG/JPEG only) |
| 422 | *UnprocessableEntityError |
Validation error on semantic parameters |
| 429 | *RateLimitError |
Rate limit hit; provides RetryAfter() (time.Duration, bool)
|
| 529 | *OverloadedError |
Service temporarily overloaded; provides RetryAfter()
|
| 5xx | *InternalServerError |
Server-side failure |
| Any other non-2xx | *APIError |
Generic HTTP failure fallback |
| Type | Raised for |
|---|---|
*SDKError |
Invalid configuration or input, an unencodable body, an unreadable response. Never an unsuccessful status code. |
*APIConnectionError |
The request never produced an HTTP response (DNS, TLS, connection failure). |
*APITimeoutError |
The request exceeded its timeout; carries Timeout time.Duration. |
*APIResponseValidationError |
A success status whose body does not match the schema; carries FieldPath. |
*ScoreError |
A score question with an empty rubric or fewer than 2 levels. |
*APIError carries the full response context:
| Field | Meaning |
|---|---|
Status |
HTTP status code |
Body |
Decoded JSON body, raw text for a non-JSON body, or nil
|
RawBody |
The exact bytes received |
Headers |
Response headers |
Endpoint |
"METHOD URL", with credentials, query, and fragment removed |
RequestID |
x-typesafe-request-id, or empty |
Message |
Human-readable detail extracted from the body |
Error() reads <METHOD URL>: <status> <message> (request_id=<id>), omitting parts that do not apply.
response, err := client.SystemOne(ctx, state, questions)
if err != nil {
var rateLimit *typesafe.RateLimitError
var payloadTooLarge *typesafe.PayloadTooLargeError
var validation *typesafe.APIResponseValidationError
var apiErr *typesafe.APIError
var timeout *typesafe.APITimeoutError
switch {
case errors.As(err, &rateLimit):
if wait, ok := rateLimit.RetryAfter(); ok {
log.Printf("rate limited, retry after %v", wait)
}
case errors.As(err, &payloadTooLarge):
log.Printf("payload too large (32 MiB body or 16 MiB image limit): %v", payloadTooLarge)
case errors.As(err, &validation):
log.Printf("invalid response field %q", validation.FieldPath)
case errors.As(err, &apiErr):
log.Printf("http %d (request_id=%s): %s", apiErr.Status, apiErr.RequestID, apiErr.Message)
case errors.As(err, &timeout):
log.Printf("timed out after %v", timeout.Timeout)
default:
log.Printf("system one failed: %v", err)
}
return err
}Match most-specific first: *RateLimitError, *PayloadTooLargeError, and other subclasses also unwrap to *APIError.
The same checks are available as helper functions, each returning (value, bool):
| Helper | Matches |
|---|---|
typesafe.AsAPIError(err) |
Any HTTP failure |
typesafe.AsRateLimitError(err) |
HTTP 429 (or compatible HTTP 529) |
typesafe.AsOverloadedError(err) |
HTTP 529 |
typesafe.AsPayloadTooLargeError(err) |
HTTP 413 |
typesafe.AsUnsupportedMediaTypeError(err) |
HTTP 415 |
typesafe.AsTimeoutError(err) |
A timeout |
typesafe.AsValidationError(err) |
A malformed success response |
if ptlErr, ok := typesafe.AsPayloadTooLargeError(err); ok {
log.Printf("413: %s", ptlErr.Message)
}The SDK derives Message from the response body, understanding formats commonly produced by APIs and reverse proxies:
| Body | Message |
|---|---|
{"error": "..."} |
the string |
{"error": {"message": "..."}} |
the nested message |
{"message": "..."} |
the string |
{"detail": "..."} |
the string |
{"detail": {"message": "..."}} |
the nested message |
{"detail": [{"loc": [...], "msg": "..."}]} |
path: msg joined with ; , with leading body location segment removed |
| a bare JSON string | the string |
| anything else | the raw body, truncated to 200 bytes with …
|
- 指南
- Guides