Error Handling
Where errors come from, how they're structured, and how to handle them in your application.
Where Errors Come From
Errors can originate at different points in the authentication flow. Understanding the source helps you decide how to handle them and what to show the user.
Browser / OS
The browser or operating system blocks the request. For example, the user cancelled the consent prompt, or the browser doesn't support the Digital Credentials API.
Frontend SDK
The client SDK catches an issue before or after calling the backend. Validation errors, network failures, timeouts, or unexpected responses.
Backend SDK / API
Your backend receives an error from Glide's API when calling prepare, getPhoneNumber, or verifyPhoneNumber. These come as HTTP status codes with structured error responses.
Carrier / Infrastructure
The carrier's service is unavailable, the credential exchange failed, or there's a platform/carrier eligibility issue. These surface through the backend SDK.
Error Categories
Rather than handling every specific error code, we recommend grouping errors into categories and handling each category consistently.
| Category | Examples | Retryable? | Recommended Action |
|---|---|---|---|
| User Action | User cancelled prompt, dismissed App Clip | Yes | Show a CTA to try again (must be from user gesture) |
| Validation | Invalid phone number, missing parameters | No | Show input error, let user correct |
| Session | Session expired, session not found | Restart | Start a new session from the beginning |
| Verification | Phone mismatch, credential invalid, verification failed | Restart | Show error, offer retry or fallback auth |
| Eligibility | Carrier not supported, platform not supported, browser not supported | No | Offer fallback authentication (e.g., OTP) |
| Network / Transient | Network error, timeout, service unavailable | Yes | Auto-retry with backoff, then show error |
| Rate Limiting | Too many requests (429) | After delay | Wait and retry (check Retry-After header) |
| Server | Internal server error (500), bad gateway (502) | Maybe | Retry once, then show generic error |
| Auth / Config | Invalid API key (401), misconfigured credentials | No | Check your integration configuration |
Error Structure
Both the frontend and backend SDKs return structured error objects with consistent fields for programmatic handling.
Frontend SDK (Web Client)
{
code: "USER_CANCELLED",
message: "Authentication was cancelled.",
status: undefined,
cause: Error,
browserError: {
name: "NotAllowedError",
message: "..."
},
context: {
step: "invoke",
timestamp: "..."
}
} Use isAuthError() to type-check and err.code to determine the error category.
Backend SDK (Node)
{
name: "MagicalAuthError",
code: "CARRIER_NOT_ELIGIBLE",
message: "Carrier not supported",
status: 422,
requestId: "req-abc123",
timestamp: "2025-01-15T09:30:00Z",
traceId: "trace-456",
service: "magic-auth"
} Use error.is(ErrorCode.CARRIER_NOT_ELIGIBLE) for type-safe error checking. Use error.status for HTTP status.
Best Practices
Handle by category, not by code
Group errors into categories (validation, session, network, etc.) and handle each group consistently. New error codes within a category should work with your existing handling.
Always have a fallback authentication method
For eligibility errors (carrier not supported, browser not supported), offer an alternative like SMS OTP so users can always complete their task.
Don't expose internal error codes to users
Map error codes to user-friendly messages in your application. Use the error message field as a starting point, but customize these for your product.
Log errors with request IDs
Both SDKs include requestId and traceId fields. Include these when reporting issues to Glide for faster debugging.
Re-invocation requires a user gesture
After a user-cancelled error, the retry must be triggered from a user click. The browser blocks programmatic re-invocation of the Digital Credentials API and App Clips.