Error handling

The Go SDK uses Go's standard error interface and the errors.As / errors.Is functions for error handling. Errors fall into three main categories: structured server errors from SurrealDB, per-statement query errors, and transport-level failures.

This page covers how to identify and handle each error type, and which errors are safe to retry.

API References

Error typeDescription
ServerErrorStructured error from SurrealDB v3 with kind, details, and cause chain
QueryErrorPer-statement query failure returned within QueryResult
RPCErrorRPC error (deprecated in favor of ServerError on v3)

Handling structured server errors

SurrealDB v3 returns structured errors with a Kind, Message, Details, and an optional Cause chain. Use errors.As to extract a ServerError:

import "errors"

_, err := surrealdb.Select[Person](ctx, db, models.NewRecordID("persons", "missing"))
if err != nil {
var se *surrealdb.ServerError
if errors.As(err, &se) {
fmt.Println("Kind:", se.Kind)
fmt.Println("Message:", se.Message)
if se.Cause != nil {
fmt.Println("Caused by:", se.Cause.Message)
}
}
}

The Cause field forms a linked list. Use errors.Unwrap or iterate through Cause to traverse the full chain.

Handling query errors

When using Query, individual statements can fail without causing the entire call to error. Each QueryResult has an Error field that contains a QueryError if that statement failed.

results, err := surrealdb.Query[[]any](ctx, db,
"SELECT * FROM persons; INVALID STATEMENT;",
nil,
)

for i, qr := range *results {
if qr.Error != nil {
fmt.Printf("Statement %d failed: %s\n", i, qr.Error.Message)
}
}

The err returned by Query is a joined error containing all per-statement QueryError values. You can check it directly:

if errors.Is(err, &surrealdb.QueryError{}) {
fmt.Println("One or more statements failed")
}

Handling sentinel errors

The SDK defines several sentinel errors for common failure conditions:

ErrorDescription
constants.ErrSessionsNotSupportedSessions require a WebSocket connection
constants.ErrTransactionsNotSupportedInteractive transactions require a WebSocket connection
constants.ErrSessionClosedThe session has been detached
constants.ErrTransactionClosedThe transaction has been committed or canceled

Check for these using errors.Is:

import "github.com/surrealdb/surrealdb.go/pkg/constants"

if errors.Is(err, constants.ErrSessionClosed) {
fmt.Println("Session was already detached")
}

Deciding whether to retry

Not all errors are safe to retry. Use the following guidelines:

Error typeRetriableReason
ServerErrorSometimesDepends on the error kind; network-related kinds may be retriable
QueryErrorNoThe query itself is invalid or caused a logical error
RPCError (from Query)YesThe RPC failed before the query was processed
RPCError (from other methods)NoMay indicate a data-level error (e.g., duplicate record)
Unmarshal errorsNoType mismatch between expected and actual response

Learn more