# Error handling

Handle exceptions and feature-support errors raised by the SurrealDB Kotlin SDK.

Networked operations on the SDK throw a [`SurrealException`](/docs/reference/kotlin/api/errors.md) on failure, or you can use the [`Result` variants](/docs/reference/kotlin/concepts/executing-queries.md#result-variants) to handle failures functionally without exceptions.

The error kinds, wire codes and structured shape behind these are documented once in [Errors](/docs/reference/rest-api/errors.md), which applies to every SDK and protocol.

## Exception hierarchy

All SDK exceptions extend the sealed base [`SurrealException`](/docs/reference/kotlin/api/errors.md).

| Exception | Raised when |
|---|---|
| [`SurrealTransportException`](/docs/reference/kotlin/api/errors.md#transport) | The connection fails or drops |
| [`SurrealProtocolException`](/docs/reference/kotlin/api/errors.md#protocol) | A malformed or unexpected protocol message is received |
| [`SurrealRpcException`](/docs/reference/kotlin/api/errors.md#rpc) | The server returns an RPC error (carries `code` and `data`) |
| [`SurrealAuthenticationException`](/docs/reference/kotlin/api/errors.md#authentication) | Authentication fails (a subclass of `SurrealRpcException`) |
| [`SurrealFeatureNotSupportedException`](/docs/reference/kotlin/api/errors.md#feature-not-supported) | A feature is unavailable on the current transport |

## Catching exceptions

Because [`SurrealException`](/docs/reference/kotlin/api/errors.md) is a sealed class, you can exhaustively branch on it with `when`.

```kotlin
import com.surrealdb.kotlin.error.SurrealAuthenticationException
import com.surrealdb.kotlin.error.SurrealException
import com.surrealdb.kotlin.error.SurrealRpcException
import com.surrealdb.kotlin.error.SurrealTransportException

try {
    client.signin(buildJsonObject {
        put("user", "root")
        put("pass", "wrong")
    })
} catch (e: SurrealAuthenticationException) {
    println("bad credentials: ${e.message}")
} catch (e: SurrealRpcException) {
    println("server error ${e.code}: ${e.message}")
} catch (e: SurrealTransportException) {
    println("connection problem: ${e.message}")
} catch (e: SurrealException) {
    println("unexpected: ${e.message}")
}
```

## Feature support errors

Calling a feature that the current transport does not support - for example a [live query](/docs/reference/kotlin/concepts/live-queries.md) over HTTP - throws [`SurrealFeatureNotSupportedException`](/docs/reference/kotlin/api/errors.md#feature-not-supported). Guard against this with [`.supports()`](/docs/reference/kotlin/api/core/surreal-client.md#supports).

```kotlin
import com.surrealdb.kotlin.SurrealFeature

if (client.supports(SurrealFeature.LiveQueries)) {
    val subscription = client.live("person")
}
```

## Using Result variants

Each networked method has a `...Result` companion that wraps the outcome in a [`Result`](https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-result/) instead of throwing.

```kotlin
client.queryResult("SELECT * FROM person")
    .onSuccess { println("got $it") }
    .onFailure { println("failed: ${it.message}") }
```

## Learn more

- [Errors reference](/docs/reference/kotlin/api/errors.md) for every exception type
- [Features and events](/docs/reference/kotlin/api/features.md) for checking transport support
- [Executing queries](/docs/reference/kotlin/concepts/executing-queries.md) for the `Result` variants
