You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: README.md
+22-11
Original file line number
Diff line number
Diff line change
@@ -47,7 +47,7 @@ The following functions only do something `if err != nil`, and act as a replacem
47
47
funcOnError(errerror) {} // panics with an error which wraps err
48
48
funcOnErrore(errerror, panicErrerror) {} // panics with an error which wraps panicErr and returns fmt.Sprintf("%v: %v", panicErr, err) for Error()
49
49
funcOnErrorfw(errerror, formatstring, args ...interface{}) {} // panics with an error which wraps err and returns fmt.Sprintf("%s: %v", fmt.Sprintf(format, args...), err) for Error()
50
-
funcOnErrorfv(errerror, formatstring, args ...interface{}) {} // panics with an error which returns fmt.Sprintf("%s: %v", fmt.Sprintf(format, args...), err) for Error()
50
+
funcOnErrorfv(errerror, formatstring, args ...interface{}) {} // panics with an error which does not wrap err and returns fmt.Sprintf("%s: %v", fmt.Sprintf(format, args...), err) for Error()
51
51
```
52
52
53
53
### panic to panic with more information
@@ -63,13 +63,14 @@ Use `Wrap()` and `Wrapf()` with the `defer`-statement.
63
63
64
64
```go
65
65
funcToError(retErr *error) {} // assigns result of recover() to *retErr
66
+
funcToErrorWithTrace(retErr *error) {} // like ToError(), but also contains full stack trace in the error's message
66
67
```
67
68
68
-
Use `ToError()` with the `defer`-statement.
69
+
Use `ToError()`and `ToErrorWithTrace()`with the `defer`-statement.
69
70
70
71
#### an important footnote
71
72
72
-
To prevent unwanted recovery and deescalation of panics originating from programming errors, panik will never lastingly recover from panics created with `panic()`. Specifically, you need to use [one of panik's panicking functions](#error-to-panic) for `defer ToError(err)` to set `*err`.
73
+
To prevent unwanted recovery and deescalation of panics originating from programming errors, panik will never lastingly recover from panics created with `panic()`. Specifically, you need to use [one of panik's panicking functions](#error-to-panic) for `defer ToError(&err)` to set `*err`.
73
74
74
75
### inspect recovered panic value
75
76
@@ -80,15 +81,13 @@ func Caused(r interface{}) bool {} // returns true if r was recovered from a pan
80
81
### print a stack trace
81
82
82
83
```go
83
-
funcRecoverTrace() {} // to stderr
84
84
funcRecoverTraceTo(wio.Writer) {} // to w
85
85
funcRecoverTraceFunc(f func(trace string)) {} // to whatever else, e.g. an error dialog box (convenience function)
86
-
funcExitTrace() {} // like RecoverTrace(), followed by os.Exit(2)
87
86
funcExitTraceTo(wio.Writer) {} // like RecoverTraceTo(), followed by os.Exit(2)
88
87
funcExitTraceFunc(f func(trace string)) {} // like RecoverTraceFunc(), followed by os.Exit(2)
89
88
```
90
89
91
-
Use `RecoverTrace`(`To`)`()` in libraries. Use `ExitTrace`(`To`)`()` in `main()`.
90
+
Use `RecoverTrace`(`Func`)`()` in libraries. Use `ExitTrace`(`Func`)`()` in `main()`.
defer panik.RecoverTrace() // if the panic could not be handled, end it all with some logging
118
+
defer panik.RecoverTraceTo(os.Stderr) // if the panic could not be handled, end it all with some logging
120
119
everythingChannel<-getEverything()
121
120
}
122
121
123
122
funcgetAnotherThing(idint) interface{} {
124
123
if id == 42 {
125
-
panik.Panicf("id %d is not supported", id) // panic from scratch when you have no non-nil error at hand
124
+
panik.Panicf("cannot handle id %d", id) // panic from scratch when you have no non-nil error at hand
126
125
}
127
126
return things[id]
128
127
}
128
+
129
+
funcDoSomething() (retErrerror) {
130
+
defer panik.ToError(&retErr)
131
+
panik.OnErrorfv(doSomethingInternal(), "could not do something") // eliminate type information about type "superSpecificError".
132
+
133
+
}
134
+
135
+
funcdoSomethingInternal() error {
136
+
// ...
137
+
return &superSpecificError{}
138
+
}
129
139
```
130
140
131
141
## Remarks
132
142
* Use `panik.ToError()` at API boundaries. APIs which panic are not idiomatic Go.
143
+
* Use `panik.ToErrorWithTrace()` if your error message is not informative enough by itself, but use it sparingly: stack traces are associated with programming errors; this will look bad if you don't know what the caller is going to do with the returned error.
133
144
* Avoid calling `recover()` yourself. If you do, you take the responsibility of differing between panics caused by your code and panics of unknown origin using `panik.Caused()`. Also, [panik's trace-printing functions](#print-a-stack-trace) will have no visibility of the original panic. You basically lose all of the simplicity panik provides. It is adviced to use `panik.ToError()` instead.
134
-
* You will still need to think about when to wrap an error and when to merely format its message; the types of wrapped errors are part of your API contract. See the difference between `OnErrorfw()`and `OnErrorfv()`.
145
+
* You will still need to think about when to wrap an error and when to merely format its message; the types of wrapped errors are part of your API contract. See `OnErrorfv()`if you do not want to wrap an error.
0 commit comments