Errors and recovery
Handle login, spending, configuration, and provider failures appropriately.
Catch Enlitt errors around the model operation. Specific classes are exported
from @enlitt/sdk/core, with compatibility exports from @enlitt/sdk/server.
Use the stable code for diagnosis, and show users a message they can act on.
User actions
| Class | Code | Action |
|---|---|---|
EnlittLoginRequiredError | personal_login_required | Start your application's Enlitt login flow again. |
EnlittLimitExceededError | spending_limit_exceeded | Explain the rule in limitRule; offer the supplied authorizeUrl when available. |
EnlittInsufficientCreditsError | premium_balance_exhausted, standard_balance_exhausted | Offer the supplied authorizeUrl to manage credits. A premium error may include admissibleMaxChargeNanoUsd. |
EnlittSubscriptionInactiveError | subscription_inactive | Ask the user to review their account. Investigate repeated occurrences: users normally retain a free plan. |
Login errors direct users to your login route. The four spending/credit codes
spending_limit_exceeded, premium_balance_exhausted,
standard_balance_exhausted, and subscription_inactive may carry
authorizeUrl. It is optional; do not assume every refusal includes a link.
Integration problems
| Class | Code | Check on your server |
|---|---|---|
EnlittConfigurationError | configuration_invalid | Server-only imports, secret, HTTPS base URL, session middleware, and pricing options. |
EnlittAuthenticationError | invalid_api_key | Key validity and revocation status. |
EnlittAuthorizationError | insufficient_permissions | Key type and application binding. |
Keep configuration and authentication details in your business logs. Show a generic service error to the user. Never log a secret or session token.
Example recovery
This server-side helper returns a simple result your UI can render:
import {
EnlittLoginRequiredError,
EnlittLimitExceededError,
EnlittInsufficientCreditsError,
EnlittSubscriptionInactiveError
} from "@enlitt/sdk/core";
export async function runForUser<T>(run: () => Promise<T>) {
try {
return { ok: true as const, value: await run() };
} catch (error) {
if (error instanceof EnlittLoginRequiredError) {
return {
ok: false as const,
message: "Sign in with Enlitt to continue.",
href: "/auth/enlitt/login"
};
}
if (
error instanceof EnlittLimitExceededError ||
error instanceof EnlittInsufficientCreditsError ||
error instanceof EnlittSubscriptionInactiveError
) {
return {
ok: false as const,
message: "Review your Enlitt spending settings or credits.",
href: error.authorizeUrl
};
}
throw error; // Let your server's error handler log and handle other failures.
}
}Retry behavior
Admission refusals such as login, spending, and exhausted-credit errors are
non-retryable. Repeating them cannot repair the user's account or settings.
EnlittRateLimitError (rate_limit_exceeded) is retryable and can carry
retryAfterMs. The SDK handles bounded rate-limit waiting; the defaults are
three attempts and a 30-second total wait budget. Set
rateLimit: { maxAttempts: 1 } to handle that wait yourself.
The codes server_error and provider_error also have a retryable marker.
The marker does not mean every SDK adapter automatically retries them.
Keep the same idempotency identity when retrying a logical call.
Other Enlitt failures use the base EnlittError shape with their stable code,
including unknown codes from newer servers. Leave a fallback in code-based handling.
The base is documented as a type; use the named runtime subclasses in examples.
A premium provider's own errors are rethrown unchanged.
Terminal-report failures go to onTerminalReportError; they do not replace
successful provider output. Monitor that hook separately from user-facing failures.