Closed
Conversation
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Structured error handling for SurrealDB v3
Adds full support for the structured error format introduced in SurrealDB v3.
What changed
V3 detail format support — SurrealDB v3 switched from serde externally-tagged enums (
{"Auth": "TokenExpired"}) to an internally-tagged format ({"kind": "Auth", "details": {"kind": "TokenExpired"}}). New helpers (detailKind,detailInner,getDetailString) handle the v3 format while retaining full backward compatibility with the old format.Recursive cause chain —
ServerErrornow carries acause *ServerErrorfield, matching Rust'scause: Option<Box<Error>>. The chain is parsed recursively from both RPC errors and query result errors. Since Go has no automatic error-chain display (unlike JS'sError.causeor Python's__cause__),Error()now joins the full cause chain with": "so the complete context is visible in logs. A newMessage()method returns just the current error's message without the chain.Cause chain traversal —
ServerCause(),Unwrap(),HasKind(), andFindCause()methods on*ServerError, plus top-levelHasKind(err, kind)andFindCause(err, kind)functions that work on anyerror.Kind-aware
errors.Is—Is()now supports optional kind matching:errors.Is(err, &ServerError{})matches any server error (catch-all), whileerrors.Is(err, &ServerError{kind: "NotFound"})only matches that specific kind.New detail accessors —
SessionID()andTargetName()for parity with the Python SDK. Updated doc comments onNamespaceName()andDatabaseName()to reflect they work for bothNotFoundandAlreadyExistskinds.Double-wrapped details unwrapping — The server's query result path may double-wrap details (e.g.
{"kind": "AlreadyExists", "details": {"kind": "Record", ...}}).parseQueryErrornow detects and unwraps this so detail accessors likeRecordID()work correctly.Integration tests — New
contrib/testenv/structured_errors_integration_test.govalidates structured errors against a live SurrealDB v3 instance: invalid credentials, parse errors,THROW, duplicate records, schema violations, and mixed multi-statement queries.CI — Updated test matrix from
v3.0.0-beta.2tov3.0.0GA.Lint cleanup — Resolved all 32 pre-existing golangci-lint issues across the codebase (gosec, gocritic, gofmt, misspell, staticcheck, unparam). The repo now passes
golangci-lint run ./...with zero issues.API surface
Test plan
HasKind,FindCause,UnwrapError()chain formatting andMessage()isolationIs()matchingSessionID()andTargetName()accessors (V3 and old format)golangci-lint run ./...passes with 0 issues