-
Notifications
You must be signed in to change notification settings - Fork 60
Description
Overview
We aim to overhaul the error design in the go-tarantool client library to follow Go’s standard error handling patterns as closely as possible. This will improve debuggability, testability, interoperability with standard library functions like errors.Is and errors.As, and overall developer experience for users of the package.
This effort is inspired by Go’s official guidance on error handling and best practices from the community (see references below).
Goals
-
Adopt Go’s error wrapping conventions
- Implement the
Unwrap() errormethod on custom error types to support error unwrapping. - Avoid implementing
Is(target error) boolunless absolutely necessary for complex matching logic.
- Implement the
-
Introduce sentinel errors
Define clear, exported, package-level sentinel errors for common failure modes:var ( ErrConnectionNotReady = errors.New("client connection is not ready") ErrConnectionClosed = errors.New("connection closed by client") // ... others as needed )
-
Establish a layered error hierarchy
Build a meaningful error chain that reflects both the origin and semantics of the error:ClientError -> RetryableError -> <Sentinel Error>ClientError: wraps errors that originate from the client side (e.g., malformed requests).RetryableError: indicates transient failures that may succeed on retry.- Sentinel errors provide the root cause and are used for comparison via
errors.Is.
-
Rename
tarantool.Error→tarantool.ServerError
Clarify that this error type represents errors returned by the Tarantool server,
not generic package errors. -
Provide ergonomic helper functions
Add convenience functions to simplify error inspection:func IsRetryable(err error) bool // equivalent to errors.Is(err, ErrRetryable) func IsClientError(err error) bool func IsServerError(err error) bool // optional but helpful
These should be implemented using
errors.Isorerrors.Asunder the hood. -
Improve error construction practices
- Prefer using constructor functions (e.g.,
NewClientError(...)) over direct struct literals. - If struct initialization is unavoidable, always use keyed fields for clarity and future-proofing:
err := &ClientError{ Code: 42, Message: "something went wrong", }
- Prefer using constructor functions (e.g.,
References
To ensure consistency with Go community standards, please review the following:
- Go Wiki: Errors
- DigitalOcean: Handling Errors in Go
- DigitalOcean: Creating Custom Errors in Go
- DigitalOcean: Adding Extra Information to Errors
Checklist
- Define sentinel errors (
ErrConnectionNotReady, etc.) - Implement
ServerError(renamed fromtarantool.Error) - Create
ClientErrorandRetryableErrorwrapper types withUnwrap()support - Add helper functions:
IsRetryable,IsClientError,IsServerError - Update all internal error creation paths to use constructors or keyed struct literals
- Add unit tests verifying error chains and
errors.Is/errors.Asbehavior - Update documentation and examples to reflect new error patterns
- Update CHANGELOG.md and MIGRATION.md