Overview
@authrim/core provides a structured error system with classification, severity levels, and recovery guidance. All SDK errors are instances of AuthrimError.
AuthrimError
import { AuthrimError } from ' @authrim/core ' ;
const tokens = await client . handleCallback (url);
if (error instanceof AuthrimError ) {
console . log (error . code ); // e.g., 'invalid_state'
console . log (error . message ); // Human-readable description
console . log (error . details ); // Additional context (object)
console . log (error . cause ); // Underlying error (if any)
console . log (error . meta ); // Classification metadata
AuthrimError Properties
Property Type Description codeAuthrimErrorCodeMachine-readable error code messagestringHuman-readable error description detailsRecord<string, unknown> | undefinedAdditional context causeError | undefinedUnderlying error metaAuthrimErrorMeta | undefinedClassification metadata
Each error includes metadata that guides recovery:
import { getErrorMeta } from ' @authrim/core ' ;
const meta = getErrorMeta (error);
console . log (meta . severity ); // 'fatal' | 'error' | 'warning'
console . log (meta . transient ); // Is this a temporary issue?
console . log (meta . retryable ); // Can this be retried?
console . log (meta . retryAfterMs ); // Suggested wait before retry
console . log (meta . maxRetries ); // Max retry attempts
console . log (meta . userAction ); // What the user should do
Property Type Description severity'fatal' | 'error' | 'warning'Error severity transientbooleanWhether the error is temporary retryablebooleanWhether the operation can be retried retryAfterMsnumber | undefinedSuggested delay before retry (ms) maxRetriesnumber | undefinedMaximum retry attempts userActionstringSuggested user action
User Actions
Action Description 'retry'User can retry the operation 'reauthenticate'User needs to log in again 'contact_support'Unrecoverable error 'check_network'Network connectivity issue 'none'No user action required (SDK handles it)
Error Classification
Use classifyError() to categorize errors programmatically:
import { classifyError, isRetryableError } from ' @authrim/core ' ;
await client . token . getAccessToken ();
if (error instanceof AuthrimError ) {
const classification = classifyError (error);
if ( isRetryableError (error)) {
Error Codes
OAuth / OIDC Errors
Code Severity Retryable Description oauth_errorerror No Generic OAuth error invalid_requesterror No Malformed request unauthorized_clientfatal No Client not authorized access_deniederror No User denied access invalid_scopeerror No Invalid scope requested server_errorerror Yes Server error temporarily_unavailableerror Yes Server temporarily unavailable invalid_granterror No Invalid authorization code or refresh token
State / PKCE Errors
Code Severity Retryable Description invalid_statefatal No State mismatch (possible CSRF) expired_stateerror No State expired nonce_mismatchfatal No Nonce mismatch in ID token missing_codeerror No No authorization code in callback missing_stateerror No No state parameter in callback missing_id_tokenerror No No ID token in response
Token Errors
Code Severity Retryable Description token_expirederror No Access token expired token_errorerror Yes Token operation failed refresh_errorerror Yes Token refresh failed token_exchange_errorerror Yes Token exchange failed no_tokenserror No No tokens available
Network Errors
Code Severity Retryable Description network_errorerror Yes Network request failed timeout_errorerror Yes Request timed out
Session Errors
Code Severity Retryable Description session_expirederror No Session has expired login_requirederror No User needs to log in interaction_requirederror No User interaction required consent_requirederror No User consent required account_selection_requirederror No Account selection required
Security Feature Errors
Code Severity Retryable Description par_errorerror Yes PAR request failed par_requirederror No Server requires PAR no_par_endpointerror No PAR endpoint not available dpop_key_generation_errorerror Yes DPoP key generation failed dpop_proof_generation_errorerror Yes DPoP proof generation failed jar_signing_errorerror No JAR signing failed jar_requirederror No Server requires JAR jarm_validation_errorerror No JARM validation failed jarm_signature_invalidfatal No JARM signature invalid
Device Flow Errors
Code Severity Retryable Description device_authorization_errorerror Yes Device authorization failed device_authorization_expirederror No Device code expired device_access_deniederror No User denied device authorization
System Errors
Code Severity Retryable Description not_initializedfatal No Client not initialized no_discoveryerror Yes Discovery document not available
Retry Logic
The SDK provides built-in retry utilities:
withRetry()
Automatically retry a function with exponential backoff:
import { withRetry } from ' @authrim/core ' ;
const result = await withRetry (
() => client . token . getAccessToken () ,
RetryOptions
Parameter Type Default Description maxRetriesnumber3Maximum retry attempts baseDelayMsnumber1000Base delay in milliseconds maxDelayMsnumber10000Maximum delay in milliseconds backoffMultipliernumber2Exponential backoff multiplier
calculateBackoffDelay()
Calculate the delay for a specific retry attempt:
import { calculateBackoffDelay } from ' @authrim/core ' ;
const delay = calculateBackoffDelay (attempt , baseMs);
createRetryFunction()
Create a reusable retry-wrapped function:
import { createRetryFunction } from ' @authrim/core ' ;
const getTokenWithRetry = createRetryFunction (
() => client . token . getAccessToken () ,
const token = await getTokenWithRetry ();
Error Event Integration
Errors are automatically emitted as events:
import { emitClassifiedError } from ' @authrim/core ' ;
// The SDK does this internally, but you can listen for the events:
client . on ( ' error:fatal ' , ( event ) => {
// Unrecoverable — redirect to login or show error page
console . error ( ' Fatal: ' , event . error . code );
client . on ( ' error:recoverable ' , ( event ) => {
// SDK may retry automatically
console . warn ( ' Recoverable: ' , event . error . code );
Practical Error Handling Patterns
Login Flow
const tokens = await client . handleCallback (url);
if ( ! (error instanceof AuthrimError )) throw error;
// Security issue or timeout — restart login
showMessage ( ' You denied the login request. ' );
case ' temporarily_unavailable ' :
showMessage ( ' Server is temporarily unavailable. Please try again. ' );
showMessage ( ` Login failed: ${ error . message } ` );
API Calls
const token = await client . token . getAccessToken ();
const data = await callApi (token);
if ( ! (error instanceof AuthrimError )) throw error;
const meta = getErrorMeta (error);
if (meta . userAction === ' reauthenticate ' ) {
} else if (meta . userAction === ' check_network ' ) {
showMessage ( ' Please check your internet connection. ' );
} else if (meta . retryable ) {
await withRetry ( () => client . token . getAccessToken (), { maxRetries: 3 });
Next Steps