README.md improved

This commit is contained in:
Timon Ringwald 2020-09-09 14:06:31 +02:00
parent b33b40c9ff
commit 37acf646f4
5 changed files with 99 additions and 9 deletions

View File

@ -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
```

View File

@ -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()
} }

View File

@ -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)

View File

@ -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),
}
}

View File

@ -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