README.md improved
This commit is contained in:
parent
b33b40c9ff
commit
37acf646f4
75
README.md
75
README.md
@ -83,4 +83,77 @@ func doStuffWrapped() error {
|
|||||||
fmt.Println(adverr.Trace())
|
fmt.Println(adverr.Trace())
|
||||||
```
|
```
|
||||||
|
|
||||||
###
|
### Example of a printed error
|
||||||
|
Code:
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"adverr"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrDoStuffFailed = adverr.NewErrTmpl("ErrDoStuffFailed", "Could'nt do stuff because of %s")
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := doStuffInAnotherGoroutine()
|
||||||
|
if err != nil {
|
||||||
|
adverr.Fatalln(err, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func doStuff() error {
|
||||||
|
err := doGoNativeStuff()
|
||||||
|
if err != nil {
|
||||||
|
return ErrDoStuffFailed.Wrap(err, "reasons")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func doStuffInAnotherGoroutine() error {
|
||||||
|
ch := make(chan error, 1)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
ch <- doStuff()
|
||||||
|
close(ch)
|
||||||
|
}()
|
||||||
|
|
||||||
|
err := <-ch
|
||||||
|
if err != nil {
|
||||||
|
return adverr.Wrap("Goroutine failed because of errors", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func doGoNativeStuff() error {
|
||||||
|
return errors.New("some go error")
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
Output:
|
||||||
|
```
|
||||||
|
adverr.Error: Goroutine failed because of errors
|
||||||
|
at main.doStuffInAnotherGoroutine (/home/user/go/src/test/main.go:38)
|
||||||
|
at main.main (/home/user/go/src/test/main.go:13)
|
||||||
|
at runtime.main (/usr/local/go/src/runtime/proc.go:204)
|
||||||
|
Caused by ErrDoStuffFailed: Could'nt do stuff because of reasons
|
||||||
|
at main.doStuff (/home/user/go/src/test/main.go:22)
|
||||||
|
at main.doStuffInAnotherGoroutine.func1 (/home/user/go/src/test/main.go:32)
|
||||||
|
Caused by errors.errorString: some go error
|
||||||
|
(Unknown source)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Globals
|
||||||
|
You can set the maximum limit of the call stack trace via
|
||||||
|
```go
|
||||||
|
adverr.CallStackLength = 50 // default value: 100
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are in a productive environment, consider disabling call traces completely for performance reasons:
|
||||||
|
```go
|
||||||
|
adverr.DisableTrace = true // default value: false
|
||||||
|
```
|
13
calltrace.go
13
calltrace.go
@ -1,6 +1,7 @@
|
|||||||
package adverr
|
package adverr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -9,19 +10,21 @@ import (
|
|||||||
// CallTrace represents a call stack trace similar to Java's stack trace
|
// CallTrace represents a call stack trace similar to Java's stack trace
|
||||||
type CallTrace struct {
|
type CallTrace struct {
|
||||||
frames *runtime.Frames
|
frames *runtime.Frames
|
||||||
|
more bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trace returns a new CallTrace starting from this call
|
// Trace returns a new CallTrace starting from this call
|
||||||
// Use skip to skip the first entries in the trace
|
// Use skip to skip the first entries in the trace
|
||||||
func Trace(skip int) *CallTrace {
|
func Trace(skip int) *CallTrace {
|
||||||
if !TraceCallStack {
|
if DisableTrace {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
pc := make([]uintptr, CallStackLength)
|
pc := make([]uintptr, CallStackLength+1)
|
||||||
n := runtime.Callers(skip+1, pc)
|
n := runtime.Callers(skip+1, pc)
|
||||||
pc = pc[:n]
|
pc = pc[:n]
|
||||||
return &CallTrace{runtime.CallersFrames(pc)}
|
fmt.Println(n, CallStackLength)
|
||||||
|
return &CallTrace{runtime.CallersFrames(pc), n == CallStackLength+1}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ct *CallTrace) String() string {
|
func (ct *CallTrace) String() string {
|
||||||
@ -42,5 +45,9 @@ func (ct *CallTrace) String() string {
|
|||||||
b.WriteString("\n")
|
b.WriteString("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ct.more {
|
||||||
|
b.WriteString("\t ...\n")
|
||||||
|
}
|
||||||
|
|
||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
2
error.go
2
error.go
@ -89,7 +89,7 @@ func printErr(err error, b *strings.Builder) {
|
|||||||
b.WriteString(errtype(err))
|
b.WriteString(errtype(err))
|
||||||
b.WriteString(": ")
|
b.WriteString(": ")
|
||||||
b.WriteString(err.Error())
|
b.WriteString(err.Error())
|
||||||
b.WriteString("\n")
|
b.WriteString("\n\t(Unknown source)\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
cause := errors.Unwrap(err)
|
cause := errors.Unwrap(err)
|
||||||
|
@ -33,3 +33,13 @@ func (t *ErrTmpl) New(args ...interface{}) *Error {
|
|||||||
callTrace: Trace(2),
|
callTrace: Trace(2),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wrap returns a new Error with a given cause in which args are being formatted into the format string of its template
|
||||||
|
func (t *ErrTmpl) Wrap(cause error, args ...interface{}) *Error {
|
||||||
|
return &Error{
|
||||||
|
msg: fmt.Sprintf(t.format, args...),
|
||||||
|
cause: cause,
|
||||||
|
tmpl: t,
|
||||||
|
callTrace: Trace(2),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package adverr
|
package adverr
|
||||||
|
|
||||||
// TraceCallStack decides if any call stack traces will be gathered when creating Errors
|
// DisableTrace decides if any call stack traces will be gathered when creating Errors
|
||||||
// If your application is doing performance-heavy tasks with lots of Error creations, you may consider setting this to false
|
// If your application is doing performance-heavy tasks with lots of Error creations, you may consider setting this to true
|
||||||
// If set to false, all CallTraces in Error will be nil
|
// If set to true, all CallTraces in Error will be nil
|
||||||
var TraceCallStack bool = true
|
var DisableTrace bool = true
|
||||||
|
|
||||||
// CallStackLength decides how many calls from the call stack should be gathered at most
|
// CallStackLength decides how many calls from the call stack should be gathered at most
|
||||||
var CallStackLength int = 100
|
var CallStackLength int = 100
|
||||||
|
Loading…
Reference in New Issue
Block a user