Skip to content

Xerror

Package xerror implements helpers for errors.

Source:

Usage:

go
import (
    "github.com/duke-git/lancet/v2/xerror"
)

Index

Documentation

New

Creates a new XError pointer instance with message.

Signature:

go
type XError struct {
    id      string
    message string
    stack   *stack
    cause   error
    values  map[string]any
}

func New(format string, args ...any) *XError

Example:Run

go
package main

import (
    "fmt"
    "github.com/duke-git/lancet/v2/xerror"
)

func main() {
    err := xerror.New("error")
    fmt.Println(err.Error())

    // Output:
    // error
}

Wrap

Creates a new XError pointer instance based on error object, and add message.

Signature:

go
func Wrap(cause error, message ...any) *XError

Example:Run

go
package main

import (
    "fmt"
    "github.com/duke-git/lancet/v2/xerror"
)

func main() {
    err := xerror.New("wrong password")
    wrapErr := xerror.Wrap(err, "error")

    fmt.Println(wrapErr.Error())

    // Output:
    // error: wrong password
}

Unwrap

Returns unwrapped XError from err by errors.As. If no XError, returns nil.

Signature:

go
func Unwrap(err error) *XError

Example:Run

go
package main

import (
    "fmt"
    "github.com/pkg/errors"
    "github.com/duke-git/lancet/v2/xerror"
)

func main() {
    err1 := xerror.New("error").With("level", "high")
    wrapErr := errors.Wrap(err1, "oops")

    err := xerror.Unwrap(wrapErr)

    values := err.Values()
    fmt.Println(values["level"])

    // Output:
    // high
}

XError_Wrap

Creates a new XError and copy message and id to new one.

Signature:

go
func (e *XError) Wrap(cause error) *XError

Example:Run

go
package main

import (
    "fmt"
    "errors"
    "github.com/duke-git/lancet/v2/xerror"
)

func main() {
    err1 := xerror.New("error").With("level", "high")
    err2 := err1.Wrap(errors.New("invalid username"))

    fmt.Println(err2.Error())

    // Output:
    // error: invalid username
}

XError_Unwrap

Compatible with github.com/pkg/errors.

Signature:

go
func (e *XError) Unwrap() error

Example:Run

go
package main

import (
    "fmt"
    "github.com/duke-git/lancet/v2/xerror"
)

func main() {
    err1 := xerror.New("error").With("level", "high")
    err2 := err1.Wrap(errors.New("invalid username"))

    err := err2.Unwrap()

    fmt.Println(err.Error())

    // Output:
    // invalid username
}

XError_With

Adds key and value related to the XError object.

Signature:

go
func (e *XError) With(key string, value any) *XError

Example:Run

go
package main

import (
    "fmt"
    "github.com/duke-git/lancet/v2/xerror"
)

func main() {
    err := xerror.New("error").With("level", "high")

    errLevel := err.Values()["level"]

    fmt.Println(errLevel)

    // Output:
    // high
}

XError_Id

Sets XError object id to check equality in XError.Is.

Signature:

go
func (e *XError) Id(id string) *XError

Example:Run

go
package main

import (
    "fmt"
    "github.com/duke-git/lancet/v2/xerror"
)

func main() {
    err1 := xerror.New("error").Id("e001")
    err2 := xerror.New("error").Id("e001")
    err3 := xerror.New("error").Id("e003")

    equal := err1.Is(err2)
    notEqual := err1.Is(err3)

    fmt.Println(equal)
    fmt.Println(notEqual)

    // Output:
    // true
    // false
}

XError_Is

Checks if target error is XError and Error.id of two errors are matched.

Signature:

go
func (e *XError) Is(target error) bool

Example:Run

go
package main

import (
    "fmt"
    "github.com/duke-git/lancet/v2/xerror"
)

func main() {
    err1 := xerror.New("error").Id("e001")
    err2 := xerror.New("error").Id("e001")
    err3 := xerror.New("error").Id("e003")

    equal := err1.Is(err2)
    notEqual := err1.Is(err3)

    fmt.Println(equal)
    fmt.Println(notEqual)

    // Output:
    // true
    // false
}

XError_Values

Returns map of key and value that is set by With. All wrapped xerror.XError key and values will be merged. Key and values of wrapped error is overwritten by upper xerror.XError.

Signature:

go
func (e *XError) Values() map[string]any

Example:Run

go
package main

import (
    "fmt"
    "github.com/duke-git/lancet/v2/xerror"
)

func main() {
    err := xerror.New("error").With("level", "high")

    errLevel := err.Values()["level"]

    fmt.Println(errLevel)

    // Output:
    // high
}

XError_StackTrace

Returns stack trace which is compatible with pkg/errors.

Signature:

go
func (e *XError) StackTrace() StackTrace

Example:Run

go
package main

import (
    "fmt"
    "github.com/duke-git/lancet/v2/xerror"
)

func main() {
    err := xerror.New("error")

    stacks := err.Stacks()

    fmt.Println(stacks[0].Func)
    fmt.Println(stacks[0].Line)

    containFile := strings.Contains(stacks[0].File, "xxx.go")
    fmt.Println(containFile)
}

XError_Info

Returns information of xerror, which can be printed.

Signature:

go
func (e *XError) Info() *errInfo

Example:Run

go
package main

import (
    "fmt"
    "github.com/duke-git/lancet/v2/xerror"
)

func main() {
    cause := errors.New("error")
    err := xerror.Wrap(cause, "invalid username").Id("e001").With("level", "high")

    errInfo := err.Info()

    fmt.Println(errInfo.Id)
    fmt.Println(errInfo.Cause)
    fmt.Println(errInfo.Values["level"])
    fmt.Println(errInfo.Message)

    // Output:
    // e001
    // error
    // high
    // invalid username
}

XError_Error

Error implements standard error interface.

Signature:

go
func (e *XError) Error() string

Example:Run

go
package main

import (
    "fmt"
    "github.com/duke-git/lancet/v2/xerror"
)

func main() {
    err := xerror.New("error")
    fmt.Println(err.Error())

    // Output:
    // error
}

TryUnwrap

TryUnwrap if err is nil then it returns a valid value. If err is not nil, Unwrap panics with err.

Signature:

go
func TryUnwrap[T any](val T, err error) T

Example:Run

go
package main

import (
    "fmt"
    "github.com/duke-git/lancet/v2/xerror"
)

func main() {
    result1 := xerror.TryUnwrap(strconv.Atoi("42"))
    fmt.Println(result1)

    _, err := strconv.Atoi("4o2")
    defer func() {
        v := recover()
        result2 := reflect.DeepEqual(err.Error(), v.(*strconv.NumError).Error())
        fmt.Println(result2)
    }()

    xerror.TryUnwrap(strconv.Atoi("4o2"))

    // Output:
    // 42
    // true
}

TryCatch

Simple simulation of Java-style try-catch. It does not align with Go's error-handling philosophy. It is recommended to use it with caution.

Signature:

go
func NewTryCatch(ctx context.Context) *TryCatch

func (tc *TryCatch) Try(tryFunc func(ctx context.Context) error) *TryCatch

func (tc *TryCatch) Catch(catchFunc func(ctx context.Context, err error)) *TryCatch

func (tc *TryCatch) Finally(finallyFunc func(ctx context.Context)) *TryCatch

func (tc *TryCatch) Do()

Example:Run

go
package main

import (
    "fmt"
    "github.com/duke-git/lancet/v2/xerror"
)

func main() {
    calledFinally := false
    calledCatch := false

    tc := xerror.NewTryCatch(context.Background())

    tc.Try(func(ctx context.Context) error {
        return errors.New("error message    ")
    }).Catch(func(ctx context.Context, err error) {
        calledCatch = true
        // Error in try block at /path/xxx.go:{line_number} - Cause: error message
        // fmt.Println(err.Error())
    }).Finally(func(ctx context.Context) {
        calledFinally = true
    }).Do()

    fmt.Println(calledCatch)
    fmt.Println(calledFinally)

    // Output:
    // true
    // true
}