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

# Error handling

> Handle structured exceptions thrown by the Portal Android SDK using the PortalException hierarchy.

The Portal Android SDK uses a structured `PortalException` hierarchy so you can catch errors at the granularity you need — from individual error cases up to broad categories. Every exception thrown by the SDK is a subclass of `PortalException`, which itself extends `Exception`.

## Exception hierarchy

`PortalException` is a sealed class with eight category-level sealed subclasses:

| Category                      | Description                                                  |
| ----------------------------- | ------------------------------------------------------------ |
| `PortalException.Mpc`         | MPC key generation, backup, recovery, and signing operations |
| `PortalException.Storage`     | Google Drive, Passkey, and Keychain storage operations       |
| `PortalException.Wallet`      | Wallet state and availability                                |
| `PortalException.Transaction` | Transaction building and asset transfers                     |
| `PortalException.Api`         | HTTP requests, RPC calls, and API errors                     |
| `PortalException.Connect`     | PortalConnect (WalletConnect) operations                     |
| `PortalException.Provider`    | Provider request routing and validation                      |
| `PortalException.Blockchain`  | Chain ID parsing and namespace resolution                    |

## Catching exceptions

Because the hierarchy is sealed, you can catch at any level of specificity.

### Catch a specific exception

```kotlin theme={null}
try {
    portal.backupWallet(backupMethod = BackupMethods.Passkey)
} catch (e: PortalException.Mpc.BackupMethodNotConfigured) {
    println("Passkey backup is not configured: ${e.message}")
} catch (e: PortalException.Storage.PasskeyNotSupported) {
    println("This device does not support passkeys: ${e.message}")
}
```

### Catch an entire category

```kotlin theme={null}
try {
    portal.backupWallet()
} catch (e: PortalException.Mpc) {
    println("MPC operation failed: ${e.message}")
} catch (e: PortalException.Storage) {
    println("Storage operation failed: ${e.message}")
}
```

### Catch any Portal exception

```kotlin theme={null}
try {
    portal.createWallet().getOrThrow()
} catch (e: PortalException) {
    println("Portal error: ${e.message}")
}
```

### Handle errors from `Result`-returning methods

Some methods like `sendAsset` return a `Result` instead of throwing. Use `onFailure` or `exceptionOrNull()` to inspect the error:

```kotlin theme={null}
portal.sendAsset(
    chainId = "eip155:11155111",
    params = SendAssetParams(to = "0x...", amount = "0.01", token = "NATIVE")
).onSuccess { txHash ->
    println("Transaction sent: $txHash")
}.onFailure { e ->
    when (e) {
        is PortalException.Transaction.SendAssetArgumentError ->
            println("Invalid parameters: ${e.message}")
        is PortalException ->
            println("Portal error: ${e.message}")
        else ->
            println("Unexpected error: ${e.message}")
    }
}
```

## Exception reference

### MPC (`PortalException.Mpc`)

| Exception                             | Description                                                                                                                                                                                                                   |
| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BackupShareNotFound`                 | No backup share found for the specified backup method.                                                                                                                                                                        |
| `OrganizationBackupShareNotFound`     | No organization backup share found for the specified backup method.                                                                                                                                                           |
| `WalletNotFound`                      | No wallet found for the specified backup method.                                                                                                                                                                              |
| `MpcVersionNoLongerSupported`         | The MPC operation is not supported on the current MPC version. Upgrade to `v6`.                                                                                                                                               |
| `WalletModificationAlreadyInProgress` | Another wallet modification operation (generate, backup, recover) is already running.                                                                                                                                         |
| `MpcResultError`                      | The MPC server returned an error. Exposes `id` (the error identifier string) and `error` (a `PortalError` with `id` and `message`). See [MPC error codes](/resources/error-codes) for the full list of server-side error IDs. |
| `UnableToDeriveShareId`               | Could not derive a share ID from the generated share.                                                                                                                                                                         |
| `UnableToReadShares`                  | Failed to read shares from storage.                                                                                                                                                                                           |
| `BackendStorageFailed`                | Failed to store data on Portal's backend.                                                                                                                                                                                     |
| `ClientCipherTextNotFound`            | No client cipherText found for the specified backup method during recovery.                                                                                                                                                   |
| `UnableToReadFromBackupStorage`       | Failed to read data from backup storage.                                                                                                                                                                                      |
| `UnableToReadFromKeychain`            | Failed to read data from keychain storage.                                                                                                                                                                                    |
| `UnableToNotifyEjection`              | Could not notify Portal of the ejection request.                                                                                                                                                                              |
| `NoPrivateKeysEjected`                | No private keys could be ejected.                                                                                                                                                                                             |
| `ShareFormattingError`                | Error formatting shares during ejection.                                                                                                                                                                                      |
| `NoFormattedSharesData`               | No data found in the formatted shares response.                                                                                                                                                                               |
| `InstanceNotAvailable`                | The MPC instance is not available.                                                                                                                                                                                            |
| `BackupMethodNotConfigured`           | The specified backup method has not been configured on the Portal instance. See [back up a wallet](./back-up-a-wallet) for configuration steps.                                                                               |
| `UnsupportedCurve`                    | The specified cryptographic curve is not supported.                                                                                                                                                                           |
| `Eip155WalletNotFound`                | No EIP-155 wallet found. Call `createWallet()` first.                                                                                                                                                                         |

### Storage (`PortalException.Storage`)

| Exception                          | Description                                                     |
| ---------------------------------- | --------------------------------------------------------------- |
| `GoogleDriveWriteFailed`           | Failed to write to Google Drive.                                |
| `GoogleDriveVerificationFailed`    | Could not verify the file was saved to Google Drive.            |
| `GoogleDriveFilenameError`         | Cannot determine filename without a configured API.             |
| `GoogleDriveClientDataUnavailable` | Client data is not available for Google Drive operations.       |
| `GoogleDriveHashesError`           | Error retrieving hashes from Google Drive.                      |
| `PasskeySessionIdNotFound`         | No session ID found during passkey operations.                  |
| `PasskeyOperationError`            | A passkey operation failed.                                     |
| `KeychainValidationError`          | Keychain validation failed.                                     |
| `UserRecoverableGDriveException`   | A user-recoverable Google Drive authentication error.           |
| `StorageAuthError`                 | Storage authentication failed.                                  |
| `PasskeyNotSupported`              | Passkeys are not supported on this device.                      |
| `PasskeyStorageNotConfigured`      | Passkey storage has not been configured on the Portal instance. |

### Wallet (`PortalException.Wallet`)

| Exception            | Description                                                                                                                                                                                                  |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `WalletNotOnDevice`  | No wallet share is available on device storage. The user needs to [recover their wallet](./recover-a-wallet). See [wallet lifecycle states](./manage-wallet-lifecycle-states) for handling this proactively. |
| `InvalidWalletState` | The wallet is in an invalid state for the requested operation.                                                                                                                                               |

### Transaction (`PortalException.Transaction`)

| Exception                    | Description                                                                                                      |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `InvalidTransactionResponse` | The response from the transaction was an unexpected type.                                                        |
| `SendAssetArgumentError`     | Invalid arguments passed to `sendAsset` (missing parameters, invalid chain ID format, or unsupported namespace). |

### API (`PortalException.Api`)

| Exception            | Description                                                    |
| -------------------- | -------------------------------------------------------------- |
| `YieldApiBadRequest` | The Yield API returned a 400 Bad Request error.                |
| `HttpRequestFailed`  | An HTTP request failed with a non-success status code.         |
| `RpcError`           | An RPC request failed. Contains `code` and `message` fields.   |
| `HttpUnauthorized`   | An HTTP request returned 401 Unauthorized. Check your API key. |

### Connect (`PortalException.Connect`)

| Exception              | Description                                       |
| ---------------------- | ------------------------------------------------- |
| `InvalidRequestMethod` | The WalletConnect request method is invalid.      |
| `InvalidRequestParams` | The WalletConnect request parameters are invalid. |

### Provider (`PortalException.Provider`)

| Exception                          | Description                                                |
| ---------------------------------- | ---------------------------------------------------------- |
| `InvalidRequestParams`             | The provider request parameters are invalid.               |
| `NoAddress`                        | No address was found for the requested chain.              |
| `NoRpcUrlFoundForChainId`          | No RPC URL is configured for the given chain ID.           |
| `NoSignatureFoundInSignResult`     | The signing operation completed but returned no signature. |
| `UnsupportedRequestMethod`         | The request method is not supported on this chain.         |
| `NoBindingForSigningApprovalFound` | No signing approval callback is registered.                |
| `UserDeclinedApproval`             | The user declined the transaction approval prompt.         |

### Blockchain (`PortalException.Blockchain`)

| Exception                        | Description                                                                                     |
| -------------------------------- | ----------------------------------------------------------------------------------------------- |
| `InvalidChainId`                 | The chain ID string is malformed (missing `:` separator). Contains the invalid `chainId` value. |
| `NoSupportedCurveForChainId`     | No supported cryptographic curve found for the given chain ID.                                  |
| `NoSupportedNamespaceForChainId` | No supported namespace found for the given chain ID.                                            |

## Migration from previous versions

In previous versions of the Android SDK, errors were thrown as generic `Error`, `Exception`, or flat `PortalException` subclasses like `SendAssetArgumentError` and `PortalHttpUnauthorizedException`. These legacy classes are now deprecated and will be removed in a future major version.

### What changed

* All generic `Error(...)` and `Exception(...)` throws have been replaced with specific `PortalException` subclasses.
* Flat exception classes (`SendAssetArgumentError`, `PortalHttpUnauthorizedException`, `PasskeyNotSupportedException`, `PasskeyStorageNotConfiguredException`, `MpcError`, `InvalidWalletStateError`, `StorageAuthError`) now extend their corresponding `PortalException` subcategory. Your existing `catch` blocks will still work, but you should migrate to the new types.

### Before and after

```kotlin theme={null}
// Before — catching a flat legacy class
try {
    portal.backupWallet()
} catch (e: PortalHttpUnauthorizedException) {
    println("Unauthorized: ${e.message}")
} catch (e: Exception) {
    println("Something went wrong: ${e.message}")
}

// After — catching the structured exception
try {
    portal.backupWallet()
} catch (e: PortalException.Api.HttpUnauthorized) {
    println("Unauthorized: ${e.message}")
} catch (e: PortalException.Mpc) {
    println("MPC error: ${e.message}")
} catch (e: PortalException.Storage) {
    println("Storage error: ${e.message}")
}
```

### Deprecated classes mapping

| Deprecated class                       | Replace with                                          |
| -------------------------------------- | ----------------------------------------------------- |
| `SendAssetArgumentError`               | `PortalException.Transaction.SendAssetArgumentError`  |
| `PortalHttpUnauthorizedException`      | `PortalException.Api.HttpUnauthorized`                |
| `PasskeyNotSupportedException`         | `PortalException.Storage.PasskeyNotSupported`         |
| `PasskeyStorageNotConfiguredException` | `PortalException.Storage.PasskeyStorageNotConfigured` |
| `MpcError`                             | `PortalException.Mpc.MpcResultError`                  |
| `InvalidWalletStateError`              | `PortalException.Wallet.InvalidWalletState`           |
| `StorageAuthError`                     | `PortalException.Storage.StorageAuthError`            |
