PartyLayerDocs
Try Demo

Error Handling

PartyLayer provides 12 typed error classes with stable error codes, human-readable messages, and structured metadata. All errors extend PartyLayerError.

PartyLayerError

typescript
class PartyLayerError extends Error {
  code: ErrorCode;       // Stable string error code
  message: string;       // Human-readable error message
  cause?: unknown;       // Original error (if wrapped)
  details?: Record<string, unknown>; // Additional context
  isOperational: boolean; // true for expected errors, false for bugs

  toJSON(): {
    name: string;
    message: string;
    code: string;
    isOperational: boolean;
    details?: Record<string, unknown>;
    cause?: unknown;
  };
}

Error Codes

CodeClassDescription
WALLET_NOT_FOUNDWalletNotFoundErrorNo adapter registered for the requested walletId.
WALLET_NOT_INSTALLEDWalletNotInstalledErrorWallet was found in registry but not detected on the device.
USER_REJECTEDUserRejectedErrorUser declined the connection or signing request in the wallet UI.
ORIGIN_NOT_ALLOWEDOriginNotAllowedErrorWallet rejected the dApp origin (domain not whitelisted).
SESSION_EXPIREDSessionExpiredErrorThe active session has expired. User must reconnect.
CAPABILITY_NOT_SUPPORTEDCapabilityNotSupportedErrorThe wallet does not support the requested capability (e.g., signTransaction).
TRANSPORT_ERRORTransportErrorCommunication failure with the wallet (PostMessage, deep link, etc.).
REGISTRY_FETCH_FAILEDRegistryFetchFailedErrorCould not fetch the wallet registry. SDK falls back to adapters.
REGISTRY_VERIFICATION_FAILEDRegistryVerificationFailedErrorRegistry signature verification failed (possible tampering).
REGISTRY_SCHEMA_INVALIDRegistrySchemaInvalidErrorRegistry data did not match the expected schema.
INTERNAL_ERRORInternalErrorUnexpected internal SDK error. This is a bug — please report it.
TIMEOUTTimeoutErrorOperation timed out (e.g., wallet took too long to respond).

Try-Catch Patterns

Catching Specific Errors

typescript
import {
  UserRejectedError,
  WalletNotInstalledError,
  TimeoutError,
  SessionExpiredError,
} from '@partylayer/core';

try {
  const session = await client.connect({ walletId: 'console' });
} catch (error) {
  if (error instanceof UserRejectedError) {
    // User clicked "Reject" in the wallet UI
    showToast('Connection cancelled');
  } else if (error instanceof WalletNotInstalledError) {
    // Wallet not detected
    showInstallPrompt(error.details?.installUrl);
  } else if (error instanceof TimeoutError) {
    // Wallet didn't respond in time
    showToast('Connection timed out. Please try again.');
  } else if (error instanceof SessionExpiredError) {
    // Session expired
    showToast('Session expired. Please reconnect.');
  } else {
    // Unexpected error
    console.error('Unexpected error:', error);
  }
}

Catching by Error Code

You can also match on the stable code property:

typescript
import { PartyLayerError } from '@partylayer/core';

try {
  await client.signMessage({ message: 'Hello' });
} catch (error) {
  if (error instanceof PartyLayerError) {
    switch (error.code) {
      case 'USER_REJECTED':
        console.log('User declined');
        break;
      case 'CAPABILITY_NOT_SUPPORTED':
        console.log('Wallet cannot sign messages');
        break;
      case 'SESSION_EXPIRED':
        console.log('Session expired, reconnecting...');
        break;
      default:
        console.error('SDK error:', error.code, error.message);
    }
  }
}

Error Event Subscription

Subscribe to all SDK errors globally:

typescript
client.on('error', (event) => {
  const { error } = event;
  console.error(`[${error.code}] ${error.message}`);

  // Report to error tracking service
  if (!error.isOperational) {
    // This is a bug — report it
    Sentry.captureException(error);
  }
});
💡 Tip
isOperational is true for expected errors like user rejection or timeout. It's false for unexpected internal errors that indicate a bug.

React Hook Error States

All action hooks expose an error state:

tsx
import { useConnect, useSignMessage } from '@partylayer/react';

function App() {
  const { connect, error: connectError, reset: resetConnect } = useConnect();
  const { signMessage, error: signError } = useSignMessage();

  return (
    <div>
      <button onClick={() => connect()}>Connect</button>
      {connectError && (
        <div className="error">
          <p>{connectError.message}</p>
          <button onClick={resetConnect}>Try Again</button>
        </div>
      )}

      <button onClick={() => signMessage({ message: 'Hi' })}>Sign</button>
      {signError && <p className="error">{signError.message}</p>}
    </div>
  );
}

Error Serialization

All errors support JSON serialization for logging and error reporting:

typescript
try {
  await client.connect({ walletId: 'unknown' });
} catch (error) {
  if (error instanceof PartyLayerError) {
    console.log(JSON.stringify(error.toJSON(), null, 2));
    // {
    //   "name": "WalletNotFoundError",
    //   "message": "Wallet 'unknown' not found",
    //   "code": "WALLET_NOT_FOUND",
    //   "isOperational": true,
    //   "details": { "walletId": "unknown" }
    // }
  }
}
PreviousCIP-0103 ProviderNextTypeScript Types