errors

package
v0.22.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 13, 2026 License: MIT Imports: 1 Imported by: 0

README

Error Handling in QNTX

QNTX uses github.com/teranos/QNTX/errors, which wraps cockroachdb/errors for production-grade error handling.

Why cockroachdb/errors?

  • Stack traces: Automatic, lightweight stack capture
  • Rich context: Hints, details, safe PII handling
  • Network portable: Encode/decode errors across distributed systems
  • Battle-tested: Production use in CockroachDB
  • Sentry integration: Built-in error reporting

Basic Usage

Creating Errors
// New error with stack trace
err := errors.New("database connection failed")

// Formatted error
err := errors.Newf("timeout after %d seconds", timeout)
Wrapping Errors

Always wrap errors to add context at each layer:

if err := db.Query(...); err != nil {
    return errors.Wrap(err, "failed to query users")
}

// With formatting
return errors.Wrapf(err, "failed to process user %d", userID)
Checking Errors
// Check for specific error
if errors.Is(err, sql.ErrNoRows) {
    return errors.Wrap(err, "user not found")
}

// Extract custom error type
var netErr *net.OpError
if errors.As(err, &netErr) {
    // Handle network error
}

User-Facing Messages

Hints

Hints provide actionable guidance to users:

err := errors.New("connection timeout")
err = errors.WithHint(err, "try increasing the timeout value in config")
err = errors.WithHintf(err, "or check network connectivity to %s", host)

// Retrieve hints
hints := errors.GetAllHints(err)
Details

Details add technical context for debugging:

err := errors.WithDetail(err, "attempted 3 retries with exponential backoff")
err = errors.WithDetailf(err, "last attempt at %s", timestamp)

details := errors.GetAllDetails(err)

PII Protection

Use WithSafeDetails for logging sensitive data:

// Safe: userID is marked safe, email is redacted
err = errors.WithSafeDetails(err, "user_id=%d email=%s", userID, email)

// When formatted for logs, email will be redacted
log.Error(err) // Shows: "user_id=123 email=×××"

Error Formatting

err := errors.Wrap(baseErr, "failed to save user")

// Simple message
fmt.Println(err)
// Output: failed to save user: connection timeout

// Full context with stack trace
fmt.Printf("%+v\n", err)
// Output:
// failed to save user
// (1) attached stack trace
//   -- stack trace:
//   | main.saveUser
//   |     /path/to/file.go:123
//   | main.main
//   |     /path/to/file.go:45
// Wraps: (2) connection timeout
// Error types: (1) *withStack (2) *leafError

Sentinel Errors

Define package-level sentinel errors:

package db

import "github.com/teranos/QNTX/errors"

var (
    ErrNotFound = errors.New("not found")
    ErrClosed   = errors.New("database closed")
)

// Usage
if errors.Is(err, db.ErrNotFound) {
    // handle not found
}

Best Practices

Do

✓ Wrap errors at every layer

return errors.Wrap(err, "failed to save attestation")

✓ Add context about what was being attempted

return errors.Wrapf(err, "failed to connect to %s", address)

✓ Use hints for user guidance

return errors.WithHint(err, "check database credentials")

✓ Check errors with errors.Is and errors.As

if errors.Is(err, sql.ErrNoRows) { ... }
Don't

✗ Return bare errors

return err // Missing context

✗ Log AND return errors (handle errors once)

log.Error(err)
return err // Causes duplicate logging

✗ Create errors with fmt.Errorf

return fmt.Errorf("failed: %w", err) // Use errors.Wrap

Advanced Features

Context Tags

Attach key-value pairs from context.Context:

err = errors.WithContextTags(err, ctx)
Network Encoding

Transmit errors across network boundaries:

// Encode for transmission
encoded := errors.EncodeError(ctx, err)

// Decode on receiver
decoded := errors.DecodeError(ctx, encoded)
Domains

Mark errors with package domains:

err = errors.WithDomain(err, errors.PackageDomain())
domain := errors.GetDomain(err)

Full Documentation

See cockroachdb/errors documentation for complete API reference.

Documentation

Overview

Package errors provides error handling for QNTX.

This package re-exports github.com/cockroachdb/errors, providing:

  • Stack traces for debugging
  • Error wrapping and context
  • PII-safe error formatting
  • Network portability for distributed systems
  • Sentry integration

Usage:

// Create new error
err := errors.New("something went wrong")

// Wrap with context
if err := doSomething(); err != nil {
    return errors.Wrap(err, "failed to do something")
}

// Add hints for users
return errors.WithHint(err, "try increasing the timeout")

// Check errors
if errors.Is(err, sql.ErrNoRows) {
    // handle not found
}

For full documentation see: https://pkg.go.dev/github.com/cockroachdb/errors

Index

Constants

This section is empty.

Variables

View Source
var (
	New          = crdb.New
	Newf         = crdb.Newf
	Wrap         = crdb.Wrap
	Wrapf        = crdb.Wrapf
	WithStack    = crdb.WithStack
	WithMessage  = crdb.WithMessage
	WithMessagef = crdb.WithMessagef
)

Core error creation and wrapping

View Source
var (
	WithHint           = crdb.WithHint
	WithHintf          = crdb.WithHintf
	WithDetail         = crdb.WithDetail
	WithDetailf        = crdb.WithDetailf
	WithSafeDetails    = crdb.WithSafeDetails
	WithSecondaryError = crdb.WithSecondaryError
)

User-facing messages and details

View Source
var (
	Is             = crdb.Is
	IsAny          = crdb.IsAny
	As             = crdb.As
	Unwrap         = crdb.Unwrap
	UnwrapOnce     = crdb.UnwrapOnce
	UnwrapAll      = crdb.UnwrapAll
	GetAllHints    = crdb.GetAllHints
	GetAllDetails  = crdb.GetAllDetails
	FlattenHints   = crdb.FlattenHints
	FlattenDetails = crdb.FlattenDetails
)

Error inspection

View Source
var (
	Handled                 = crdb.Handled
	HandledWithMessage      = crdb.HandledWithMessage
	WithDomain              = crdb.WithDomain
	GetDomain               = crdb.GetDomain
	WithContextTags         = crdb.WithContextTags
	EncodeError             = crdb.EncodeError
	DecodeError             = crdb.DecodeError
	GetReportableStackTrace = crdb.GetReportableStackTrace
)

Advanced features

View Source
var (
	AssertionFailedf                 = crdb.AssertionFailedf
	NewAssertionErrorWithWrappedErrf = crdb.NewAssertionErrorWithWrappedErrf
)

Assertions and panics

View Source
var (
	// ErrNotFound indicates the requested resource does not exist
	ErrNotFound = New("not found")

	// ErrInvalidRequest indicates the request was malformed or invalid
	ErrInvalidRequest = New("invalid request")

	// ErrUnauthorized indicates the request lacks proper authentication
	ErrUnauthorized = New("unauthorized")

	// ErrForbidden indicates the request is not allowed for this user
	ErrForbidden = New("forbidden")

	// ErrServiceUnavailable indicates a required service is not available
	ErrServiceUnavailable = New("service unavailable")

	// ErrTimeout indicates an operation timed out
	ErrTimeout = New("operation timed out")

	// ErrConflict indicates a resource conflict (e.g., duplicate key)
	ErrConflict = New("resource conflict")
)

Common sentinel errors for use across QNTX. Use these with errors.Is() for type-safe error checking. Wrap these with errors.Wrap() to add context while preserving the type.

GetStack is an alias for GetReportableStackTrace for convenience.

Functions

func IsInvalidRequestError added in v0.20.1

func IsInvalidRequestError(err error) bool

IsInvalidRequestError checks if an error is or wraps ErrInvalidRequest

func IsNotFoundError added in v0.20.1

func IsNotFoundError(err error) bool

IsNotFoundError checks if an error is or wraps ErrNotFound. Also provides backward compatibility with string-based "not found" errors.

func IsServiceUnavailableError added in v0.20.1

func IsServiceUnavailableError(err error) bool

IsServiceUnavailableError checks if an error is or wraps ErrServiceUnavailable

func NewInvalidRequestError added in v0.20.1

func NewInvalidRequestError(format string, args ...interface{}) error

NewInvalidRequestError creates an invalid-request error with a formatted message

func NewNotFoundError added in v0.20.1

func NewNotFoundError(format string, args ...interface{}) error

NewNotFoundError creates a not-found error with a formatted message

func WrapInvalidRequest added in v0.20.1

func WrapInvalidRequest(err error, context string) error

WrapInvalidRequest wraps an error as an invalid-request error with context

func WrapNotFound added in v0.20.1

func WrapNotFound(err error, context string) error

WrapNotFound wraps an error as a not-found error with context

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL