Skip to main content

Error Hierarchy

All Chipi SDK errors extend a base ChipiError class. Each error type carries specific context to help you handle failures precisely.
ChipiError (base)
├── ChipiApiError        → HTTP errors (status code, response body)
├── ChipiAuthError       → Authentication failures (401)
├── ChipiValidationError → Invalid input (400)
├── ChipiWalletError     → Wallet operations (creation, encryption)
├── ChipiTransactionError → Transaction failures (signing, broadcasting)
├── ChipiSessionError    → Session key errors (expired, revoked, not registered)
└── ChipiSkuError        → SKU/billing operations

Type Guards

isChipiError(error)

Check if an error is any Chipi SDK error:
import { isChipiError } from "@chipi-stack/nextjs";

try {
  await createWalletAsync({ ... });
} catch (error) {
  if (isChipiError(error)) {
    // Typed as ChipiError - has .message, .code
    console.error("Chipi error:", error.message);
  } else {
    // Network error, timeout, etc.
    console.error("Unexpected error:", error);
  }
}

hasHttpStatus(error)

Check if an error has an HTTP status code. Useful for retry logic and status-specific handling:
import { hasHttpStatus } from "@chipi-stack/nextjs";

try {
  await transferAsync({ ... });
} catch (error) {
  if (hasHttpStatus(error)) {
    switch (error.status) {
      case 401:
        // Token expired - refresh and retry
        await refreshToken();
        break;
      case 429:
        // Rate limited - back off
        await delay(5000);
        break;
      case 500:
        // Server error - show retry button
        showRetryUI();
        break;
    }
  }
}

Error Patterns by Type

API Errors

import { ChipiApiError } from "@chipi-stack/nextjs";

try {
  await transferAsync({ ... });
} catch (error) {
  if (error instanceof ChipiApiError) {
    console.error(`API error ${error.status}: ${error.message}`);
    // error.status  → HTTP status code (number)
    // error.message → Human-readable error message
  }
}

Session Errors

Session errors include a .code field for precise handling:
import { ChipiSessionError } from "@chipi-stack/nextjs";

try {
  await executeWithSessionAsync({ ... });
} catch (error) {
  if (error instanceof ChipiSessionError) {
    switch (error.code) {
      case "SESSION_EXPIRED":
        // Session validUntil has passed
        await createNewSession();
        break;
      case "SESSION_NOT_REGISTERED":
        // Session not found on-chain
        await registerSession();
        break;
      case "SESSION_REVOKED":
        // Session was explicitly revoked
        await createNewSession();
        break;
      case "SESSION_MAX_CALLS_EXCEEDED":
        // remainingCalls reached 0
        await createNewSession();
        break;
      case "SESSION_ENTRYPOINT_NOT_ALLOWED":
        // Function not in allowedEntrypoints whitelist
        console.error("This action is not permitted by the session");
        break;
      case "SESSION_DECRYPTION_FAILED":
        // Wrong PIN/encryptKey
        promptForPin();
        break;
      case "INVALID_WALLET_TYPE_FOR_SESSION":
        // Wallet is READY, not CHIPI
        console.error("Session keys require a CHIPI wallet");
        break;
    }
  }
}

Session Error Codes Reference

CodeMeaningRecovery
SESSION_EXPIREDvalidUntil timestamp has passedCreate and register a new session
SESSION_NOT_REGISTEREDSession key not found on-chainCall addSessionKeyToContract
SESSION_REVOKEDSession was explicitly revokedCreate a new session
SESSION_MAX_CALLS_EXCEEDEDremainingCalls reached 0Create a new session with higher maxCalls
SESSION_ENTRYPOINT_NOT_ALLOWEDCalled function not in whitelistRegister with correct allowedEntrypoints
SESSION_DECRYPTION_FAILEDWrong PIN for session private keyPrompt user to re-enter PIN
SESSION_CREATION_FAILEDKeypair generation errorRetry the operation
SESSION_INVALID_RESPONSEMalformed contract responseCheck wallet type and contract state
INVALID_WALLET_TYPE_FOR_SESSIONWallet is READY, not CHIPIUse a CHIPI wallet for sessions

Wallet Errors

import { ChipiWalletError } from "@chipi-stack/nextjs";

try {
  await createWalletAsync({ ... });
} catch (error) {
  if (error instanceof ChipiWalletError) {
    // Wallet already exists, encryption failed, etc.
    console.error("Wallet error:", error.message);
  }
}

Auth Errors

import { ChipiAuthError } from "@chipi-stack/nextjs";

try {
  await transferAsync({ ... });
} catch (error) {
  if (error instanceof ChipiAuthError) {
    // 401 - bearer token invalid or expired
    // Refresh your auth token and retry
    const newToken = await refreshAuthToken();
    await transferAsync({ ...params, bearerToken: newToken });
  }
}

Common Pattern: Unified Error Handler

import { isChipiError, hasHttpStatus, ChipiSessionError, ChipiAuthError } from "@chipi-stack/nextjs";

function handleChipiError(error: unknown): string {
  if (error instanceof ChipiAuthError) {
    return "Your session has expired. Please sign in again.";
  }

  if (error instanceof ChipiSessionError) {
    if (error.code === "SESSION_EXPIRED" || error.code === "SESSION_MAX_CALLS_EXCEEDED") {
      return "Your session has expired. Creating a new one...";
    }
    return `Session error: ${error.message}`;
  }

  if (hasHttpStatus(error) && error.status === 429) {
    return "Too many requests. Please wait a moment.";
  }

  if (isChipiError(error)) {
    return error.message;
  }

  return "Something went wrong. Please try again.";
}
Need help? Join our Telegram Community for support.