@@ -18,9 +18,9 @@ import (
18
18
19
19
type (
20
20
// we want these to be type aliases, so they are much nicer to use
21
- PanicHandler = func (p any )
22
- ErrorHandler = func (err error ) error // this is only proper type that work
23
- NilHandler = func (err error ) error // these two are the same
21
+ PanicFn = func (p any )
22
+ ErrorFn = func (err error ) error // this is only proper type that work
23
+ NilFn = func (err error ) error // these two are the same
24
24
25
25
//CheckHandler = func(noerr bool, err error) error
26
26
CheckHandler = func (noerr bool )
@@ -41,13 +41,13 @@ type Info struct {
41
41
// These are called if handler.Process caller sets it. If they aren't set
42
42
// default implementations are used. NOTE. We have to use both which means
43
43
// that we get nilHandler call if recovery() is called by any other
44
- // handler then we call still ErrorHandler and get the error from Any. It
44
+ // handler then we call still ErrorFn and get the error from Any. It
45
45
// goes for other way around: we get error but nilHandler is only one to
46
46
// set, we use that for the error (which is accessed from the closure).
47
- ErrorHandler // If nil default implementation is used.
48
- NilHandler // If nil default (pre-defined here) implementation is used.
47
+ ErrorFn // If nil default implementation is used.
48
+ NilFn // If nil default (pre-defined here) implementation is used.
49
49
50
- PanicHandler // If nil panic() is called.
50
+ PanicFn // If nil panic() is called.
51
51
52
52
CheckHandler // this would be for cases where there isn't any error, but
53
53
// this should be the last defer.
@@ -77,8 +77,8 @@ func (i *Info) callNilHandler() {
77
77
if i .safeErr () != nil {
78
78
i .checkErrorTracer ()
79
79
}
80
- if i .NilHandler != nil {
81
- * i .Err = i .NilHandler (i .werr )
80
+ if i .NilFn != nil {
81
+ * i .Err = i .NilFn (i .werr )
82
82
i .werr = * i .Err // remember change both our errors!
83
83
} else {
84
84
i .defaultNilHandler ()
@@ -100,8 +100,8 @@ func (i *Info) checkErrorTracer() {
100
100
101
101
func (i * Info ) callErrorHandler () {
102
102
i .checkErrorTracer ()
103
- if i .ErrorHandler != nil {
104
- * i .Err = i .ErrorHandler (i .Any .(error ))
103
+ if i .ErrorFn != nil {
104
+ * i .Err = i .ErrorFn (i .Any .(error ))
105
105
i .werr = * i .Err // remember change both our errors!
106
106
} else {
107
107
i .defaultErrorHandler ()
@@ -120,8 +120,8 @@ func (i *Info) checkPanicTracer() {
120
120
121
121
func (i * Info ) callPanicHandler () {
122
122
i .checkPanicTracer ()
123
- if i .PanicHandler != nil {
124
- i .PanicHandler (i .Any )
123
+ if i .PanicFn != nil {
124
+ i .PanicFn (i .Any )
125
125
} else {
126
126
panic (i .Any )
127
127
}
@@ -153,8 +153,8 @@ func (i *Info) buildFmtErr() {
153
153
}
154
154
155
155
func (i * Info ) safeCallErrorHandler () {
156
- if i .ErrorHandler != nil {
157
- * i .Err = i .ErrorHandler (i .werr )
156
+ if i .ErrorFn != nil {
157
+ * i .Err = i .ErrorFn (i .werr )
158
158
}
159
159
}
160
160
@@ -172,8 +172,8 @@ func (i *Info) defaultNilHandler() {
172
172
}
173
173
174
174
func (i * Info ) safeCallNilHandler () {
175
- if i .NilHandler != nil {
176
- * i .Err = i .NilHandler (i .werr )
175
+ if i .NilFn != nil {
176
+ * i .Err = i .NilFn (i .werr )
177
177
}
178
178
}
179
179
@@ -285,9 +285,9 @@ func PreProcess(errPtr *error, info *Info, a ...any) error {
285
285
}
286
286
}
287
287
}
288
- defCatchCallMode := info .PanicHandler == nil && info .CallerName == "Catch"
288
+ defCatchCallMode := info .PanicFn == nil && info .CallerName == "Catch"
289
289
if defCatchCallMode {
290
- info .PanicHandler = PanicNoop
290
+ info .PanicFn = PanicNoop
291
291
}
292
292
293
293
Process (info )
@@ -317,14 +317,26 @@ func _(a ...any) bool {
317
317
}
318
318
319
319
func subProcess (info * Info , a ... any ) {
320
+ // not that switch cannot be 0: see call side
320
321
switch len (a ) {
321
- case 2 : // currently we support only this order of 2 handlers in Catch
322
+ case 0 :
323
+ msg := `---
324
+ programming error: subProcess: case 0:
325
+ ---`
326
+ fmt .Fprintln (os .Stderr , color .Red ()+ msg + color .Reset ())
327
+ case 1 :
328
+ processArg (info , 0 , a ... )
329
+ default : // case 2, 3, ...
322
330
processArg (info , 0 , a ... )
323
- if _ , ok := a [1 ].(PanicHandler ); ok {
331
+ if _ , ok := a [1 ].(PanicFn ); ok {
324
332
processArg (info , 1 , a ... )
333
+ } else if _ , ok := a [1 ].(ErrorFn ); ok {
334
+ // check second ^ and then change the rest by combining them to
335
+ // one that we set to proper places: ErrorFn and NilFn
336
+ hfn := Pipeline (AssertErrHandlers (a ))
337
+ info .ErrorFn = hfn
338
+ info .NilFn = hfn
325
339
}
326
- default :
327
- processArg (info , 0 , a ... )
328
340
}
329
341
}
330
342
@@ -333,15 +345,15 @@ func processArg(info *Info, i int, a ...any) {
333
345
case string :
334
346
info .Format = first
335
347
info .Args = a [i + 1 :]
336
- case ErrorHandler : // err2.Catch uses this
337
- info .ErrorHandler = first
338
- info .NilHandler = first
339
- case PanicHandler : // err2.Catch uses this
340
- info .PanicHandler = first
348
+ case ErrorFn : // err2.Catch uses this
349
+ info .ErrorFn = first
350
+ info .NilFn = first
351
+ case PanicFn : // err2.Catch uses this
352
+ info .PanicFn = first
341
353
case CheckHandler :
342
354
info .CheckHandler = first
343
355
case nil :
344
- info .NilHandler = NilNoop
356
+ info .NilFn = NilNoop
345
357
default :
346
358
// we don't panic here because we can already be in recovery, but lets
347
359
// try to show an RED error message at least.
@@ -386,3 +398,40 @@ func LogOutput(lvl int, s string) (err error) {
386
398
fmt .Fprintln (w , s )
387
399
return nil
388
400
}
401
+
402
+ // Pipeline is a helper to call several error handlers in a sequence.
403
+ //
404
+ // defer err2.Handle(&err, err2.Pipeline(err2.Log, MapToHTTPErr))
405
+ func Pipeline (f []ErrorFn ) ErrorFn {
406
+ return func (err error ) error {
407
+ for _ , handler := range f {
408
+ err = handler (err )
409
+ }
410
+ return err
411
+ }
412
+ }
413
+
414
+ func bugAssertErrHandlers (handlerFns ... any ) (hs []ErrorFn ) {
415
+ hs = make ([]ErrorFn , 0 , len (handlerFns ))
416
+ for _ , a := range handlerFns {
417
+ if fn , ok := a .(ErrorFn ); ok {
418
+ hs = append (hs , fn )
419
+ } else {
420
+ return nil
421
+ }
422
+ }
423
+ return hs
424
+ }
425
+
426
+ func AssertErrHandlers (handlerFns []any ) (hs []ErrorFn ) {
427
+ count := len (handlerFns )
428
+ hs = make ([]ErrorFn , 0 , count )
429
+ for _ , a := range handlerFns {
430
+ if fn , ok := a .(ErrorFn ); ok {
431
+ hs = append (hs , fn )
432
+ } else {
433
+ return nil
434
+ }
435
+ }
436
+ return hs
437
+ }
0 commit comments