# Error codes

Every error thrown by the SDK is an instance of `ArlopassSDKError` (or a subclass). Errors carry structured metadata for programmatic handling.

```tsx
import {
  ArlopassSDKError,
  ArlopassStateError,
  ArlopassTransportError,
  ArlopassTimeoutError,
  ArlopassProtocolBoundaryError,
  ArlopassInvalidStateTransitionError,
} from "@arlopass/web-sdk";
```

---

### Error hierarchy

```text
// Error class hierarchy
ArlopassSDKError                          // Base class — all SDK errors extend this
├── ArlopassStateError                    // Invalid operation for current state
├── ArlopassInvalidStateTransitionError   // Illegal state transition
├── ArlopassProtocolBoundaryError         // Protocol envelope validation failure
├── ArlopassTransportError                // Transport-layer failure (retryable by default)
└── ArlopassTimeoutError                  // Request timed out (retryable by default)
```

### Error properties

All error subclasses inherit these properties from `ArlopassSDKError`.

| Prop                 | Type                                        | Description                                              |
|----------------------|---------------------------------------------|----------------------------------------------------------|
| ` message`          | ` string`                                   | Human-readable error description.                         |
| ` machineCode`      | ` SDKMachineCode`                           | Stable machine-readable code for programmatic handling.  |
| ` reasonCode`       | ` ProtocolReasonCode`                       | Normalized reason code from the protocol layer.           |
| ` retryable`        | ` boolean`                                  | Whether this error can be retried.                        |
| ` correlationId`    | ` string | undefined`                       | Correlation ID from the failed request.                   |
| ` details`          | ` Record<string, string | number | boolean | null> | undefined` | Additional structured metadata about the error. | 
| ` cause`            | ` Error | undefined`                        | Original error that caused this one.                       |

---

### SDK machine codes

Codes prefixed with `ARLOPASS_SDK_` originate in the client SDK.

| Prop                                    | Type   | Description                                                                   |
|-----------------------------------------|--------|-------------------------------------------------------------------------------|
| ` ARLOPASS_SDK_INVALID_STATE_TRANSITION`| ` SDK` | Attempted an illegal state transition (e.g. connect while already connected).   |
| ` ARLOPASS_SDK_INVALID_STATE_OPERATION` | ` SDK` | Operation not valid in the current state (e.g. chat.send while disconnected).  |
| ` ARLOPASS_SDK_MISSING_PROVIDER_SELECTION`| ` SDK` | Chat operation attempted without selecting a provider first.                   |
| ` ARLOPASS_SDK_PROTOCOL_VIOLATION`     | ` SDK` | Response envelope failed validation.                                           |
| ` ARLOPASS_SDK_TRANSPORT_ERROR`        | ` SDK` | Transport-level failure (network, serialization, etc.).                       |

---

### Protocol machine codes

Codes prefixed with `ARLOPASS_` or `ARLOPASS_PROTOCOL_` originate in the protocol layer or extension.

| Prop                                    | Type      | Description                                                       |
|-----------------------------------------|-----------|-------------------------------------------------------------------|
| ` ARLOPASS_AUTH_FAILED`                 | ` Protocol`| Authentication failure (invalid credentials).                     |
| ` ARLOPASS_PERMISSION_DENIED`           | ` Protocol`| Caller lacks permission for the requested operation.             |
| ` ARLOPASS_TIMEOUT`                      | ` Protocol`| Request timed out.                                               |
| ` ARLOPASS_PROVIDER_UNAVAILABLE`        | ` Protocol`| Selected provider is offline or unreachable.                    |
| ` ARLOPASS_TRANSIENT_NETWORK`           | ` Protocol`| Transient network error.                                         |
| ` ARLOPASS_POLICY_VIOLATION`            | ` Protocol`| Request blocked by a policy rule.                                |
| ` ARLOPASS_PROTOCOL_INVALID_ENVELOPE`   | ` Protocol`| Envelope structure is invalid.                                   |
| ` ARLOPASS_PROTOCOL_MISSING_REQUIRED_FIELD`| ` Protocol`| A required field is missing from the envelope.                   |
| ` ARLOPASS_PROTOCOL_ENVELOPE_EXPIRED`   | ` Protocol`| Envelope TTL has expired.                                       |
| ` ARLOPASS_PROTOCOL_REPLAY_PRONE_METADATA`| ` Protocol`| Envelope metadata suggests a replay attack.                       |
| ` ARLOPASS_PROTOCOL_UNSUPPORTED_VERSION` | ` Protocol`| Protocol version not supported.                                   |
| ` ARLOPASS_PROTOCOL_UNSUPPORTED_CAPABILITY`| ` Protocol`| Requested capability not supported.                               |

---

### Reason codes

Normalized reason codes provide a human-readable classification. The SDK normalizes aliases (e.g. "timeout" → "transport.timeout").

| Prop                       | Type     | Description                                              |
|----------------------------|----------|----------------------------------------------------------|
| ` allow`                  | ` Success`| Operation succeeded.                                     |
| ` auth.invalid`          | ` Auth`   | Invalid credentials.                                     |
| ` auth.expired`          | ` Auth`   | Credentials have expired.                                 |
| ` permission.denied`     | ` Auth`   | Insufficient permissions.                                 |
| ` policy.denied`         | ` Policy` | Blocked by policy.                                      |
| ` provider.unavailable`   | ` Provider`| Provider is offline or unreachable.                      |
| ` request.invalid`       | ` Request` | Malformed request.                                      |
| ` request.replay_prone`  | ` Request` | Request metadata suggests a replay.                       |
| ` request.expired`       | ` Request` | Request envelope has expired.                             |
| ` protocol.unsupported_version`| ` Protocol` | Protocol version mismatch.                              |
| ` protocol.unsupported_capability`| ` Protocol` | Capability not recognized.                               |
| ` protocol.invalid_envelope` | ` Protocol`| Envelope validation failed.                              |
| ` transport.timeout`     | ` Transport`| Operation timed out.                                    |
| ` transport.cancelled`   | ` Transport`| Operation was cancelled (e.g. AbortSignal).            |
| ` transport.transient_failure`| ` Transport`| Temporary network or transport issue.                    |

---

### Retryable vs non-retryable

Every error has a `retryable` boolean. Use it to decide whether to surface a retry button or fail permanently.

| Prop                                      | Type       | Description                                                    |
|-------------------------------------------|------------|--------------------------------------------------------------|
| ` ArlopassTransportError`                 | ` retryable: true` | Transport failures are retryable by default.                |
| ` ArlopassTimeoutError`                   | ` retryable: true` | Timeouts are retryable by default.                           |
| ` ArlopassStateError`                     | ` retryable: false`| State errors indicate logic bugs — not retryable.            |
| ` ArlopassInvalidStateTransitionError`    | ` retryable: false`| Invalid transitions are logic bugs — not retryable.         |
| ` ArlopassProtocolBoundaryError`          | ` retryable: false`| Protocol violations typically require a code fix.           |

```tsx
if (error instanceof ArlopassSDKError && error.retryable) {
  await retry();
}
```
