Skip to main content
Version: 2.8.x(Latest)

Error Stack

The error implementation in the standard library is relatively simple and does not support stack tracing, which is not very user-friendly for the caller when an error occurs, as it cannot obtain detailed information about the error call chain. gerror supports error stack recording, and methods like New/Newf, Wrap/Wrapf, WrapSkip/WrapSkipf automatically record the stack information at the time the error occurs.

Example:

package main

import (
"fmt"
"github.com/gogf/gf/v2/errors/gerror"
)

func OpenFile() error {
return gerror.New("permission denied")
}

func OpenConfig() error {
return gerror.Wrap(OpenFile(), "configuration file opening failed")
}

func ReadConfig() error {
return gerror.Wrap(OpenConfig(), "reading configuration failed")
}

func main() {
fmt.Printf("%+v", ReadConfig())
}

Execution output example:

reading configuration failed: configuration file opening failed: permission denied
1. reading configuration failed
1). main.ReadConfig
/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/v2/geg/errors/gerror/gerror2.go:18
2). main.main
/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/v2/geg/errors/gerror/gerror2.go:25
2. configuration file opening failed
1). main.OpenConfig
/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/v2/geg/errors/gerror/gerror2.go:14
2). main.ReadConfig
/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/v2/geg/errors/gerror/gerror2.go:18
3). main.main
/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/v2/geg/errors/gerror/gerror2.go:25
3. permission denied
1). main.OpenFile
/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/v2/geg/errors/gerror/gerror2.go:10
2). main.OpenConfig
/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/v2/geg/errors/gerror/gerror2.go:14
3). main.ReadConfig
/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/v2/geg/errors/gerror/gerror2.go:18
4). main.main
/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/v2/geg/errors/gerror/gerror2.go:25
tip

The error stack path printed is the code path executed locally by the author.

As you can see, the caller can use the Wrap method to layer the underlying error information while including complete error stack information.

HasStack Determine Whether an Error Includes a Stack

  • Description: The HasStack method allows us to determine whether a given error interface object implements (contains) stack information.

  • Format:

    // HasStack checks and reports whether `err` implemented interface `gerror.IStack`.
    HasStack(err error) bool
  • Example:

    func ExampleHasStack() {
    err1 := errors.New("sql error")
    err2 := gerror.New("write error")
    fmt.Println(gerror.HasStack(err1))
    fmt.Println(gerror.HasStack(err2))

    // Output:
    // false
    // true
    }
warning

Currently, this method is implemented by checking if the error object implements the gerror.IStack interface. If the error object does not implement this interface, it cannot determine if it includes stack information.

Stack Get Stack Information

  • Description: The Stack method allows us to obtain the complete stack information of an error object, returning a stack list string.

  • Format:

    // Stack returns the stack callers as string.
    // It returns the error string directly if the `err` does not support stacks.
    Stack(err error) string
  • Example:

    func ExampleStack() {
    var err error
    err = errors.New("sql error")
    err = gerror.Wrap(err, "adding failed")
    err = gerror.Wrap(err, "api calling failed")
    fmt.Println(gerror.Stack(err))
    }

    Execution example output:

    1. api calling failed
    1). main.main
    /Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/.example/other/test.go:14
    2. adding failed
    1). main.main
    /Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/.example/other/test.go:13
    3. sql error
warning

Currently, this method is implemented by retrieving the error object's implementation of the gerror.IStack interface. If the error object does not implement this interface, this method will return an empty string.

Current Get the Current error

  • Description: The Current method is used to get the error information of the current level, returning through the error interface object.

  • Format:

    // Current creates and returns the current level error.
    // It returns nil if current level error is nil.
    Current(err error) error
  • Example:

    func ExampleCurrent() {
    var err error
    err = errors.New("sql error")
    err = gerror.Wrap(err, "adding failed")
    err = gerror.Wrap(err, "api calling failed")
    fmt.Println(err)
    fmt.Println(gerror.Current(err))

    // Output:
    // api calling failed: adding failed: sql error
    // api calling failed
    }

Unwrap Get the Next Level error

  • Description: The Unwrap method is used to get the next level error error interface object. If the next level does not exist, it returns nil.

  • Format:

    // Unwrap returns the next level error.
    // It returns nil if current level error or the next level error is nil.
    Unwrap(err error) error
  • Example 1: Simple error hierarchy access example.

    func ExampleUnwrap() {
    var err error
    err = errors.New("sql error")
    err = gerror.Wrap(err, "adding failed")
    err = gerror.Wrap(err, "api calling failed")

    fmt.Println(err)

    err = gerror.Unwrap(err)
    fmt.Println(err)

    err = gerror.Unwrap(err)
    fmt.Println(err)

    // Output:
    // api calling failed: adding failed: sql error
    // adding failed: sql error
    // sql error
    }
  • Example 2: Common iteration logic code example.

    func IsGrpcErrorNotFound(err error) bool {
    if err != nil {
    for e := err; e != nil; e = gerror.Unwrap(e) {
    if s, ok := status.FromError(e); ok && s != nil && s.Code() == codes.NotFound {
    return true
    }
    }
    }
    return false
    }

Cause Get the Root Error error

  • Description: The Cause method allows us to obtain the root error information (original error) of the error object.

  • Format:

    // Cause returns the root cause error of `err`.
    Cause(err error) error
  • Example:

    package main

    import (
    "fmt"
    "github.com/gogf/gf/v2/errors/gerror"
    )

    func OpenFile() error {
    return gerror.New("permission denied")
    }

    func OpenConfig() error {
    return gerror.Wrap(OpenFile(), "configuration file opening failed")
    }

    func ReadConfig() error {
    return gerror.Wrap(OpenConfig(), "reading configuration failed")
    }

    func main() {
    fmt.Println(gerror.Cause(ReadConfig()))
    }

    // Output:
    // permission denied