Skip to content

Error Handling

The widget handles most errors internally and displays user-friendly messages. For deeper control, listen to the error events and react accordingly.

Emitted when the operation cannot continue. The widget shows an error screen (FAILED or DISABLED).

widget.addEventListener('allfeat:failed', (e) => {
const { code, message, requestId, details } = e.detail;
console.error(`[${code}] ${message} (${requestId})`);
// Example: redirect on configuration error
if (code === 'session.origin_not_allowed') {
showMessage('This website is not authorized to use the widget.');
}
});

Emitted for recoverable errors. The widget continues operating.

widget.addEventListener('allfeat:error', (e) => {
const { code, message, requestId, stage } = e.detail;
sendToMonitoring({
code,
message,
requestId,
stage,
});
});

allfeat:token-expired — Authentication Errors

Section titled “allfeat:token-expired — Authentication Errors”

See Authentication for the full token refresh flow.

| Category | Example Codes | Widget Behavior | |----------|---------------|----------------| | Auth / Session | session.invalid_token, common.auth.expired | Triggers token refresh flow | | Configuration | session.key_inactive, session.origin_not_allowed, organization.inactive | DISABLED screen (no retry button) | | Service Unavailable | common.service_unavailable, transaction.store_unavailable | FAILED screen with retry | | Rate Limited | common.rate_limited, session.rate_limited | FAILED screen with message | | Other API Errors | registration.duplicate_title, work.not_found | FAILED screen with localized message | | Client Errors | widget.network_error, widget.upload_error | FAILED screen, no request ID |

Every API error includes a request_id (e.g., req_01HXYZ8G7K3M9Q2F4N5P6R7S8T). This ID is:

  • Shown on terminal screens (FAILED, DISABLED) with a copy button
  • Included in allfeat:failed and allfeat:error event payloads as requestId
  • Useful for support tickets — it correlates to server-side logs

Client-side errors (widget.* codes) do not have a request ID.

| Scenario | Behavior | |----------|----------| | File upload | 3 total attempts (2 retries) with exponential backoff (1s, 2s) | | Token expiry | Pauses and waits for a new token (60-second timeout) | | Rate limiting (429) | Up to 2 retries with backoff (1s, 2s, or Retry-After header) | | Transaction polling | Polls every 3s with a 120-second timeout | | Configuration errors | Not retryable — DISABLED screen without retry button | | Network errors | Displayed to the user with a FAILED screen (retry button) |

Call widget.reset() to clear the error state and return to the form:

widget.addEventListener('allfeat:failed', (e) => {
retryButton.onclick = () => widget.reset();
});

Use getState() to inspect the widget’s current state for debugging:

const state = widget.getState();
console.log(state);
// {
// screen: 'FAILED',
// jobId: '...',
// transactionId: '...',
// atsId: null,
// accessCode: undefined
// }