> ## Documentation Index
> Fetch the complete documentation index at: https://docs.privacyboost.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Error handling

# Error Handling

This guide covers error handling patterns for the Privacy Boost React SDK. For the cross-platform error code reference, see [Error Handling](/sdk/concepts/error-handling).

## Error Types

All SDK operations throw `PrivacyBoostError` on failure:

```typescript theme={null}
class PrivacyBoostError extends Error {
  code: string;
  message: string;
  retryable: boolean;
}
```

## Common Error Codes

| Code                   | Description             | Retryable |
| ---------------------- | ----------------------- | --------- |
| `NOT_AUTHENTICATED`    | User not logged in      | No        |
| `INSUFFICIENT_BALANCE` | Not enough balance      | No        |
| `TRANSACTION_REJECTED` | User rejected in wallet | No        |
| `INVALID_AMOUNT`       | Invalid amount format   | No        |
| `INVALID_RECIPIENT`    | Invalid privacy address | No        |
| `NETWORK_ERROR`        | Network request failed  | Yes       |
| `RATE_LIMITED`         | Too many requests       | Yes       |

## Basic Error Handling

```tsx theme={null}
import { useVault } from '@sunnyside-io/privacy-boost-react';

function ShieldButton() {
  const { shield } = useVault();
  const [error, setError] = useState<string | null>(null);

  const handleShield = async () => {
    setError(null);
    try {
      await shield({ tokenAddress, amount });
    } catch (err: any) {
      if (err.code === 'TRANSACTION_REJECTED') return;
      setError(err.message);
    }
  };

  return (
    <div>
      <button onClick={handleShield}>Deposit</button>
      {error && <p style={{ color: 'red' }}>{error}</p>}
    </div>
  );
}
```

## Retry Pattern

```tsx theme={null}
async function withRetry<T>(
  operation: () => Promise<T>,
  maxRetries = 3
): Promise<T> {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await operation();
    } catch (error: any) {
      if (!error.retryable || attempt === maxRetries) throw error;
      await new Promise((r) => setTimeout(r, 1000 * attempt));
    }
  }
  throw new Error('Unreachable');
}
```

## User-Friendly Error Messages

```tsx theme={null}
function userMessage(code: string): string {
  const messages: Record<string, string> = {
    NOT_AUTHENTICATED: 'Please connect your wallet first',
    INSUFFICIENT_BALANCE: 'Not enough balance',
    TRANSACTION_REJECTED: 'Transaction cancelled',
    INVALID_AMOUNT: 'Invalid amount',
    INVALID_RECIPIENT: 'Invalid recipient address',
    NETWORK_ERROR: 'Network error. Please try again.',
    RATE_LIMITED: 'Too many requests. Please wait.',
  };
  return messages[code] || 'Something went wrong. Please try again.';
}
```

## Best Practices

### 1. Always Handle Wallet Rejections Silently

```tsx theme={null}
try {
  await shield({ tokenAddress, amount });
} catch (err: any) {
  if (err.code === 'TRANSACTION_REJECTED') return;
  setError(userMessage(err.code));
}
```

### 2. Log Errors for Debugging

```tsx theme={null}
catch (err: any) {
  console.error('Operation failed:', err.code, err.message);
  setError(userMessage(err.code));
}
```

## Next Steps

* [Deposits Guide](./deposits)
* [Withdrawals Guide](./withdrawals)
* [Transfers Guide](./transfers)
* [Error Handling Concepts](/sdk/concepts/error-handling)
