> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://www.openfort.io/api/mcp` to find what you need.
>
> **Have feedback?** Use `submit_feedback` on the same MCP server.

# Error Handling

The Openfort SDK provides a comprehensive error handling system with typed error classes and error codes to help you handle specific failure scenarios gracefully.

## Error Classes

All Openfort errors extend the base `OpenfortError` class. Import the error classes you need:

```typescript
import {
  OpenfortError,
  AuthenticationError,
  AuthorizationError,
  ConfigurationError,
  OAuthError,
  OTPError,
  RecoveryError,
  RequestError,
  SessionError,
  SignerError,
  UserError,
} from '@openfort/openfort-js'
```

### OpenfortError

The base error class that all other Openfort errors extend. Contains common properties:

```typescript
class OpenfortError extends Error {
  error: string              // Error code for programmatic handling
  error_description: string  // Human-readable error description
}
```

### AuthenticationError

Thrown when authentication fails (invalid credentials, expired tokens, etc.).

```typescript
try {
  await openfort.auth.logInWithEmailPassword({ email, password })
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.log('Authentication failed:', error.message)
    // Show login error to user
  }
}
```

### AuthorizationError

Thrown when the user lacks permission to perform an action.

```typescript
try {
  await openfort.embeddedWallet.exportPrivateKey()
} catch (error) {
  if (error instanceof AuthorizationError) {
    console.log('Not authorized:', error.message)
    // Prompt user to authenticate or request access
  }
}
```

### ConfigurationError

Thrown when the SDK is misconfigured (missing keys, invalid options).

```typescript
try {
  const openfort = new Openfort({
    baseConfiguration: { publishableKey: '' }, // Missing key!
  })
} catch (error) {
  if (error instanceof ConfigurationError) {
    console.log('Configuration error:', error.message)
    // Check SDK configuration
  }
}
```

### OAuthError

Thrown when OAuth authentication fails.

```typescript
try {
  await openfort.auth.storeCredentials({ token, userId })
} catch (error) {
  if (error instanceof OAuthError) {
    console.log('OAuth error:', error.message)
    // Handle OAuth-specific error
  }
}
```

### OTPError

Thrown when OTP (one-time password) operations fail.

```typescript
try {
  await openfort.auth.logInWithEmailOtp({ email, otp })
} catch (error) {
  if (error instanceof OTPError) {
    console.log('OTP error:', error.message)
    // Show OTP-specific error (expired, invalid, etc.)
  }
}
```

### RecoveryError

Thrown when wallet recovery operations fail.

```typescript
try {
  await openfort.embeddedWallet.recover({
    account: accountId,
    recoveryParams: { recoveryMethod: RecoveryMethod.PASSWORD, password: '...' },
  })
} catch (error) {
  if (error instanceof RecoveryError) {
    console.log('Recovery failed:', error.message)
    // Handle recovery-specific error
  }
}
```

### RequestError

Thrown when API requests fail (network errors, server errors).

```typescript
try {
  await openfort.embeddedWallet.list()
} catch (error) {
  if (error instanceof RequestError) {
    console.log('Request failed:', error.message)
    // Handle network or server error
  }
}
```

### SessionError

Thrown when session operations fail (not logged in, session expired).

```typescript
try {
  await openfort.user.get()
} catch (error) {
  if (error instanceof SessionError) {
    console.log('Session error:', error.message)
    // Redirect to login
  }
}
```

### SignerError

Thrown when signer operations fail (signing, wallet not configured).

```typescript
try {
  await openfort.embeddedWallet.signMessage('Hello')
} catch (error) {
  if (error instanceof SignerError) {
    console.log('Signer error:', error.message)
    // Configure wallet first
  }
}
```

### UserError

Thrown when user operations fail (user not found, invalid user data).

```typescript
try {
  await openfort.auth.addEmail({ email, callbackURL })
} catch (error) {
  if (error instanceof UserError) {
    console.log('User error:', error.message)
    // Handle user-specific error
  }
}
```

### Embedded Wallet Error Classes

The SDK also exports additional error classes thrown during embedded wallet operations:

```typescript
import {
  MissingProjectEntropyError,
  MissingRecoveryPasswordError,
  NotConfiguredError,
  OTPRequiredError,
  WrongPasskeyError,
  WrongRecoveryPasswordError,
} from '@openfort/openfort-js'
```

| Error Class | When Thrown |
|-------------|------------|
| `MissingProjectEntropyError` | Shield encryption share is missing or not configured |
| `MissingRecoveryPasswordError` | Password recovery requires a password but none was provided |
| `NotConfiguredError` | Embedded wallet method called before `configure()` |
| `OTPRequiredError` | Operation requires OTP verification before proceeding |
| `WrongPasskeyError` | Passkey authentication failed (wrong credential) |
| `WrongRecoveryPasswordError` | Incorrect recovery password provided |

### Passkey Error Classes

The SDK exports passkey-specific error classes for handling WebAuthn operations:

```typescript
import {
  PasskeyUserCancelledError,
  PasskeyCreationFailedError,
  PasskeyPRFNotSupportedError,
  PasskeyAssertionFailedError,
  PasskeySeedInvalidError,
  PASSKEY_ERROR_CODES,
} from '@openfort/openfort-js'
```

| Error Class | When Thrown |
|-------------|------------|
| `PasskeyUserCancelledError` | User cancelled the passkey operation (expected flow, not a failure) |
| `PasskeyCreationFailedError` | Passkey creation failed unexpectedly |
| `PasskeyPRFNotSupportedError` | Device does not support PRF extension for passkeys |
| `PasskeyAssertionFailedError` | Passkey assertion (authentication) failed |
| `PasskeySeedInvalidError` | Passkey seed is invalid or corrupted |

```typescript
try {
  await openfort.embeddedWallet.configure({
    recoveryParams: { recoveryMethod: RecoveryMethod.PASSKEY },
  })
} catch (error) {
  if (error instanceof PasskeyUserCancelledError) {
    console.log('User cancelled — this is expected, not an error')
  } else if (error instanceof PasskeyPRFNotSupportedError) {
    console.log('This device does not support passkey recovery')
  }
}
```

## Error Codes

The SDK exports error code constants for programmatic error handling:

```typescript
import {
  OPENFORT_ERROR_CODES,
  OPENFORT_AUTH_ERROR_CODES,
} from '@openfort/openfort-js'
```

### Authentication Error Codes

The SDK exports 40+ error codes. Key codes organized by category:

```typescript
const OPENFORT_AUTH_ERROR_CODES = {
  // Session & auth state
  ALREADY_LOGGED_IN: 'ALREADY_LOGGED_IN',
  NOT_LOGGED_IN: 'NOT_LOGGED_IN',
  SESSION_EXPIRED: 'SESSION_EXPIRED',
  INVALID_TOKEN: 'INVALID_TOKEN',

  // Credentials
  INVALID_CREDENTIALS: 'INVALID_EMAIL_OR_PASSWORD',
  PASSWORD_TOO_SHORT: 'PASSWORD_TOO_SHORT',
  PASSWORD_TOO_LONG: 'PASSWORD_TOO_LONG',

  // User management
  USER_ALREADY_EXISTS: 'USER_ALREADY_EXISTS',
  USER_NOT_FOUND: 'USER_NOT_FOUND',
  EMAIL_NOT_VERIFIED: 'EMAIL_NOT_VERIFIED',

  // OTP
  OTP_INVALID: 'INVALID_OTP',
  OTP_EXPIRED: 'OTP_EXPIRED',
  OTP_SEND_FAILED: 'OTP_SEND_FAILED',

  // Wallet & signer
  MISSING_SIGNER: 'MISSING_SIGNER',
  WRONG_RECOVERY_PASSWORD: 'WRONG_RECOVERY_PASSWORD',
  INCORRECT_PASSKEY: 'INCORRECT_PASSKEY',
  MISSING_PROJECT_ENTROPY: 'MISSING_PROJECT_ENTROPY',
  MISSING_USER_ENTROPY: 'MISSING_USER_ENTROPY',

  // General
  OPERATION_NOT_SUPPORTED: 'OPERATION_NOT_SUPPORTED',
  REQUEST_ERROR: 'REQUEST_ERROR',
  // ... and more
}
```

:::info
For the complete and up-to-date list of error codes, refer to the [SDK source code](https://github.com/openfort-xyz/openfort-js) or use your IDE's autocompletion on `OPENFORT_AUTH_ERROR_CODES`.
:::

## Best Practices

### 1. Use `instanceof` for Type Checking

Always use `instanceof` to check error types:

```typescript
try {
  await someOpenfortOperation()
} catch (error) {
  if (error instanceof AuthenticationError) {
    // Handle authentication error
  } else if (error instanceof ConfigurationError) {
    // Handle configuration error
  } else if (error instanceof OpenfortError) {
    // Handle any other Openfort error
  } else {
    // Handle unexpected errors
    throw error
  }
}
```

### 2. Handle Errors Gracefully

Provide user-friendly messages:

```typescript
const getErrorMessage = (error: unknown): string => {
  if (error instanceof AuthenticationError) {
    return 'Invalid email or password. Please try again.'
  }
  if (error instanceof SessionError) {
    return 'Your session has expired. Please log in again.'
  }
  if (error instanceof OTPError) {
    return 'Invalid or expired code. Please request a new one.'
  }
  if (error instanceof OpenfortError) {
    return 'An error occurred. Please try again.'
  }
  return 'An unexpected error occurred.'
}
```
