Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.fanfare.io/llms.txt

Use this file to discover all available pages before exploring further.

SDK Error Reference

This reference documents all error codes returned by the Fanfare SDK, their meanings, and recommended resolutions.

Error Structure

All SDK errors follow a consistent structure:
interface FanfareError {
  message: string; // Human-readable error message
  code: string; // Machine-readable error code
  status?: number; // HTTP status code (if applicable)
  details?: unknown; // Additional error details
  requestId?: string; // Request ID for support
  correlationId?: string; // Correlation ID for tracking
  retryable: boolean; // Whether the operation can be retried
  retryAfter?: number; // Suggested retry delay in seconds
}

Handling Errors

import { FanfareError, ErrorCodes } from "@fanfare/sdk";

try {
  await client.experiences.enter(experienceId);
} catch (error) {
  if (error instanceof FanfareError) {
    switch (error.code) {
      case ErrorCodes.NETWORK_ERROR:
        // Handle network issues
        break;
      case ErrorCodes.RATE_LIMITED:
        // Wait and retry
        await delay(error.retryAfter || 5000);
        break;
      default:
      // Handle other errors
    }
  }
}

Network Errors

NETWORK_ERROR

Description: Request failed due to network connectivity issues. Common Causes:
  • No internet connection
  • DNS resolution failure
  • Network timeout
  • Server unreachable
Resolution:
if (error.code === ErrorCodes.NETWORK_ERROR) {
  // Show offline indicator
  showOfflineMessage();

  // Retry when connection is restored
  window.addEventListener("online", () => {
    retryOperation();
  });
}
Retryable: Yes

TIMEOUT

Description: Request timed out waiting for a response. Common Causes:
  • Slow network connection
  • Server under heavy load
  • Request too large
Resolution:
if (error.code === ErrorCodes.TIMEOUT) {
  // Retry with exponential backoff
  const delay = Math.min(1000 * Math.pow(2, attempt), 30000);
  await sleep(delay);
  return retry();
}
Retryable: Yes

ABORTED

Description: Request was cancelled before completion. Common Causes:
  • User navigated away from page
  • Component unmounted
  • Explicit cancellation
Resolution: This is usually intentional and doesn’t require action. Retryable: No

Authentication Errors

UNAUTHORIZED

Description: Request requires authentication. HTTP Status: 401 Common Causes:
  • No session active
  • Session was cleared
  • Invalid credentials
Resolution:
if (error.code === ErrorCodes.UNAUTHORIZED) {
  // Clear any stale auth state
  client.auth.logout();

  // Redirect to login or start guest session
  if (requiresAuth) {
    redirectToLogin();
  } else {
    await client.auth.guest();
  }
}
Retryable: No (requires re-authentication)

SESSION_EXPIRED

Description: Authentication session has expired. HTTP Status: 401 Common Causes:
  • Session timeout
  • Server-side session invalidation
  • Token expiration
Resolution:
if (error.code === ErrorCodes.SESSION_EXPIRED) {
  // Attempt to refresh the session
  try {
    await client.auth.refresh();
    // Retry the original operation
    return retry();
  } catch {
    // Refresh failed, re-authenticate
    await client.auth.guest();
  }
}
Retryable: Yes (after refresh)

INVALID_CREDENTIALS

Description: Provided credentials are incorrect. HTTP Status: 401 Common Causes:
  • Wrong email/password combination
  • Account doesn’t exist
  • Account locked
Resolution: Prompt user to verify their credentials. Retryable: No

INVALID_OTP

Description: One-time password verification failed. HTTP Status: 401 Common Causes:
  • Incorrect code entered
  • Code has expired
  • Code already used
Resolution:
if (error.code === ErrorCodes.INVALID_OTP) {
  // Clear the input and show error
  clearOtpInput();
  showError("Invalid code. Please try again or request a new code.");
}
Retryable: No (user must enter correct code)

Queue Errors

QUEUE_NOT_FOUND

Description: The specified queue does not exist. Common Causes:
  • Invalid queue ID
  • Queue has been deleted
  • Queue not yet created
Resolution: Verify the queue ID and ensure the experience is active. Retryable: No

QUEUE_EXPIRED

Description: The queue has ended and is no longer accepting entries. Common Causes:
  • Queue end time has passed
  • Queue was manually closed
  • All inventory distributed
Resolution:
if (error.code === ErrorCodes.QUEUE_EXPIRED) {
  showMessage("This queue has ended. Join the waitlist for future access.");
  offerWaitlistSignup();
}
Retryable: No

QUEUE_FULL

Description: The queue has reached maximum capacity. Common Causes:
  • Queue participant limit reached
  • High demand exceeded capacity
Resolution:
if (error.code === ErrorCodes.QUEUE_FULL) {
  showMessage("This queue is currently full.");

  if (waitlistAvailable) {
    offerWaitlistSignup();
  }
}
Retryable: No

ALREADY_IN_QUEUE

Description: User is already in this queue. Common Causes:
  • Duplicate entry attempt
  • Re-entry after page refresh
Resolution: This is informational. Retrieve the existing queue status.
if (error.code === ErrorCodes.ALREADY_IN_QUEUE) {
  // Get existing position
  const status = client.queues.getStatus(queueId);
  updateUI(status);
}
Retryable: No (not an error condition)

NOT_IN_QUEUE

Description: User is not in the specified queue. Common Causes:
  • Never entered the queue
  • Left the queue previously
  • Session mismatch
Resolution: Re-enter the queue if appropriate. Retryable: No

Validation Errors

VALIDATION_ERROR

Description: Request data failed validation. HTTP Status: 400 or 422 Common Causes:
  • Missing required fields
  • Invalid field values
  • Data format issues
Resolution:
if (error.code === ErrorCodes.VALIDATION_ERROR) {
  // Display validation errors to user
  const issues = error.details as ValidationIssue[];
  issues.forEach((issue) => {
    showFieldError(issue.path, issue.message);
  });
}
Retryable: No (requires valid data)

INVALID_PARAMETERS

Description: Request parameters are invalid. HTTP Status: 400 Common Causes:
  • Invalid ID format
  • Out-of-range values
  • Unsupported parameters
Resolution: Verify the parameters being sent. Retryable: No

Rate Limiting

RATE_LIMITED

Description: Too many requests in a short period. HTTP Status: 429 Headers:
  • X-RateLimit-Limit: Maximum requests allowed
  • X-RateLimit-Remaining: Requests remaining
  • Retry-After: Seconds to wait before retrying
Resolution:
if (error.code === ErrorCodes.RATE_LIMITED) {
  const waitTime = error.retryAfter || 5;
  showMessage(`Please wait ${waitTime} seconds before trying again.`);

  setTimeout(() => {
    enableRetry();
  }, waitTime * 1000);
}
Retryable: Yes (after delay)

Server Errors

INTERNAL_ERROR

Description: An unexpected server error occurred. HTTP Status: 500 Resolution:
if (error.code === ErrorCodes.INTERNAL_ERROR) {
  // Log for debugging
  console.error("Server error:", error.requestId);

  showMessage("Something went wrong. Please try again.");
  // Automatic retry with backoff
}
Retryable: Yes (with backoff)

SERVICE_UNAVAILABLE

Description: The service is temporarily unavailable. HTTP Status: 503 Common Causes:
  • Maintenance window
  • Capacity issues
  • Deployment in progress
Resolution:
if (error.code === ErrorCodes.SERVICE_UNAVAILABLE) {
  showMessage("Service temporarily unavailable. Retrying...");

  // SDK automatically retries
  // Show progress indicator
}
Retryable: Yes (with backoff)

SDK Configuration Errors

NOT_INITIALIZED

Description: SDK operation called before initialization. Common Causes:
  • Calling methods before creating client
  • Client creation failed
  • Async initialization not awaited
Resolution:
// Ensure client is initialized before use
const client = new FanfareClient({
  publishableKey: "pk_live_...",
});

// Then call methods
await client.experiences.enter(experienceId);
Retryable: No

ALREADY_INITIALIZED

Description: Attempted to initialize SDK when already initialized. Resolution: Use a single client instance throughout your application. Retryable: No

INVALID_CONFIG

Description: SDK configuration is invalid. Common Causes:
  • Missing required configuration
  • Invalid configuration values
  • Incompatible options
Resolution: Review your SDK configuration. Retryable: No

Fingerprint Errors

FP001 - FINGERPRINT_REQUIRED

Description: Device fingerprint is required but not provided. HTTP Status: 400 Resolution: Ensure the SDK is properly initialized with fingerprinting enabled.
const client = new FanfareClient({
  publishableKey: "pk_live_...",
  // Fingerprinting is enabled by default
});
User Message: “Device verification is required for this action. Please ensure your browser is up to date and try again.”

FP002 - DEVICE_MISMATCH

Description: Current device fingerprint doesn’t match the original device. HTTP Status: 403 Common Causes:
  • Accessing from different device
  • Browser profile changed
  • Significant browser configuration changes
Resolution: This is a security feature. User must complete the action from the original device. User Message: “This action must be completed from the same device that was originally used.”

FP003 - FINGERPRINT_INVALID

Description: Fingerprint format is invalid. HTTP Status: 400 Common Causes:
  • SDK version mismatch
  • Browser fingerprinting blocked
  • Corrupted fingerprint data
Resolution: Clear browser cache and refresh the page. User Message: “Device verification failed. Please refresh the page and try again.”

Best Practices

Error Logging

Log errors with context for debugging.
client.on("error", (error: FanfareError) => {
  console.error("Fanfare error:", {
    code: error.code,
    message: error.message,
    requestId: error.requestId,
    retryable: error.retryable,
  });

  // Send to error tracking service
  errorTracker.capture(error, {
    tags: { service: "fanfare", code: error.code },
  });
});

User-Friendly Messages

Map technical errors to user-friendly messages.
const USER_MESSAGES: Record<string, string> = {
  NETWORK_ERROR: "Connection issue. Please check your internet.",
  RATE_LIMITED: "Too many requests. Please wait a moment.",
  SESSION_EXPIRED: "Your session expired. Please refresh.",
  QUEUE_FULL: "This queue is currently full.",
  // ... more mappings
};

function getUserMessage(error: FanfareError): string {
  return USER_MESSAGES[error.code] || "Something went wrong. Please try again.";
}