SDK npm package is not published yet and API environments may be unavailable.View status
Guide · Shared

Handle errors

Catch, classify, and recover from API and SDK errors gracefully. Covers error classes, retry strategies, and user-facing error messages.

Overview

The Ananke Labs API returns structured error responses. The TypeScript SDK wraps these as typed error classes so you can catch and handle them programmatically. This guide covers every error pattern you'll encounter.

Error classes

ClassHTTP statusWhen thrown
AnankeFieldValidationError400Request body fails schema or field validation.
AnankeApiError (UNAUTHORIZED)401Missing or malformed API key.
AnankeApiError (FORBIDDEN)403Key valid but quota/entitlement check failed.
AnankeApiError (NOT_FOUND)404Resource not found under this tenant.
AnankeApiError (CONFLICT)409Duplicate detection or invalid lifecycle transition.
AnankeApiError (UNPROCESSABLE)422Semantic error (archived template, schema mismatch).
AnankeApiError (RATE_LIMITED)429Rate limit exceeded.
AnankeApiError (SERVICE_UNAVAILABLE)503Upstream dependency unavailable.

Catching errors

Catch and classify errors
import { AnankeApiError, AnankeFieldValidationError } from "@ananke/sdk";

try {
  const doc = await client.trust.documents.issue({ /* ... */ });
} catch (err) {
  if (err instanceof AnankeFieldValidationError) {
    // 400 - inspect individual field errors
    console.error("Validation failed:");
    for (const field of err.fieldErrors) {
      console.error(`  ${field.field}: ${field.message}`);
    }
  } else if (err instanceof AnankeApiError) {
    switch (err.code) {
      case "UNAUTHORIZED":
        console.error("Check your API key");
        break;
      case "FORBIDDEN":
        console.error("Quota exhausted or tenant suspended");
        break;
      case "NOT_FOUND":
        console.error("Resource not found:", err.message);
        break;
      case "CONFLICT":
        console.error("Duplicate or invalid transition:", err.message);
        break;
      case "RATE_LIMITED":
        console.error("Rate limited — retry after delay");
        break;
      case "SERVICE_UNAVAILABLE":
        console.error("Service temporarily unavailable");
        break;
      default:
        console.error("API error:", err.code, err.message);
    }
  } else {
    // Network error, timeout, etc.
    console.error("Unexpected error:", err);
  }
}

HTTP status codes

When using raw HTTP (no SDK), check the response status:

StatusMeaningAction
200 / 201SuccessProcess the response body.
400Validation errorFix the request body. Check errors array in response.
401UnauthorizedCheck x-api-key header.
403ForbiddenCheck tenant status and entitlements.
404Not foundVerify the resource ID/reference.
409ConflictHandle duplicate or invalid transition.
429Rate limitedBack off and retry.
503Service unavailableRetry after delay.

Field validation errors

The 400 response includes a structured errors array:

400 response body
{
  "status": 400,
  "code": "VALIDATION_ERROR",
  "message": "One or more fields failed validation.",
  "errors": [
    { "field": "recipientEmail", "message": "Must be a valid email address." },
    { "field": "fields[0].value", "message": "Required field 'certNumber' is missing." }
  ]
}

Retry strategy

Use the SDK's built-in retry for transient errors:

SDK retry configuration
const client = new AnankeClient({
  apiKey:       process.env.ANANKE_API_KEY!,
  retries:      3,        // retry up to 3 times on 429 / 5xx
  retryDelayMs: 500,      // initial delay (exponential backoff)
});

For manual retry logic with raw HTTP:

  • 429 — Wait for the delay indicated in the Retry-After header.
  • 503 — Use exponential backoff: 500ms, 1s, 2s, 4s.
  • 400, 401, 403, 404, 409 — Do not retry. These are client errors.

User-facing messages

Never show raw error codes to end users. Map them to friendly messages:

CodeUser message
UNAUTHORIZED"Authentication failed. Please check your credentials."
FORBIDDEN"You don't have permission for this action."
NOT_FOUND"The requested resource was not found."
RATE_LIMITED"Too many requests. Please wait and try again."
SERVICE_UNAVAILABLE"The service is temporarily unavailable. Please try again later."

Raw API error structure

Standard error response
{
  "status": 404,
  "code": "NOT_FOUND",
  "message": "No issuance found with id 'abc-123' under this tenant.",
  "traceId": "00-abc123..."
}

The traceId is useful for debugging. Include it in support requests.

Next steps