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
| Code | Class | Description |
|---|---|---|
| WALLET_NOT_FOUND | WalletNotFoundError | No adapter registered for the requested walletId. |
| WALLET_NOT_INSTALLED | WalletNotInstalledError | Wallet was found in registry but not detected on the device. |
| USER_REJECTED | UserRejectedError | User declined the connection or signing request in the wallet UI. |
| ORIGIN_NOT_ALLOWED | OriginNotAllowedError | Wallet rejected the dApp origin (domain not whitelisted). |
| SESSION_EXPIRED | SessionExpiredError | The active session has expired. User must reconnect. |
| CAPABILITY_NOT_SUPPORTED | CapabilityNotSupportedError | The wallet does not support the requested capability (e.g., signTransaction). |
| TRANSPORT_ERROR | TransportError | Communication failure with the wallet (PostMessage, deep link, etc.). |
| REGISTRY_FETCH_FAILED | RegistryFetchFailedError | Could not fetch the wallet registry. SDK falls back to adapters. |
| REGISTRY_VERIFICATION_FAILED | RegistryVerificationFailedError | Registry signature verification failed (possible tampering). |
| REGISTRY_SCHEMA_INVALID | RegistrySchemaInvalidError | Registry data did not match the expected schema. |
| INTERNAL_ERROR | InternalError | Unexpected internal SDK error. This is a bug — please report it. |
| TIMEOUT | TimeoutError | Operation 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" }
// }
}
}