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
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
HasStackmethod allows us to determine whether a givenerrorinterface 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
}
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
Stackmethod allows us to obtain the complete stack information of anerrorobject, 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
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
Currentmethod is used to get the error information of the current level, returning through theerrorinterface 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
Unwrapmethod is used to get the next level errorerrorinterface object. If the next level does not exist, it returnsnil. -
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
Causemethod allows us to obtain the root error information (original error) of theerrorobject. -
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