Created
June 21, 2018 17:41
-
-
Save dannypsnl/c4f3198af8bf97ab7489cb075b8173b7 to your computer and use it in GitHub Desktop.
Go: Error is Value
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package wrap | |
import ( | |
"reflect" | |
) | |
type ErrorWrapper struct { | |
err error | |
prevReturns []reflect.Value | |
} | |
func NewErrorWrapper(vs ...interface{}) *ErrorWrapper { | |
args := make([]reflect.Value, 0) | |
// if no vs, nothing happened | |
for _, v := range vs { | |
args = append(args, reflect.ValueOf(v)) | |
} | |
return &ErrorWrapper{ | |
err: nil, | |
prevReturns: args, | |
} | |
} | |
func (w *ErrorWrapper) Then(task interface{}) *ErrorWrapper { | |
rTask := reflect.TypeOf(task) | |
// here reflect.Type.NumOut promise: | |
// 1. task is a function(else NumOut will panic) | |
// 2. < 1 mean, task has at least return 1 value | |
if rTask.NumOut() < 1 { | |
panic("at least return error at the end") | |
} | |
if w.err == nil { | |
vTask := reflect.ValueOf(task) | |
lenOfReturn := rTask.NumOut() | |
// reflect.Value.Call using []reflect.Value as it's arguments. | |
res := vTask.Call(w.prevReturns) | |
// res[lenOfReturn-1] mean error at here | |
// | |
// for example: | |
// Then(func() (string, error) { return "", nil }) | |
// | |
// lenOfReturns = 2 | |
// res[0] is string | |
// res[1] is error, 1 = lenOfReturns - 1 | |
// | |
// this check is because when error = nil, it can't convert to type error | |
if res[lenOfReturn-1].Interface() != nil { | |
w.err = res[lenOfReturn-1].Interface().(error) | |
} | |
// prepare next task's arguments(when we want to passing some result to next task) | |
w.prevReturns = res[:lenOfReturn-1] | |
} | |
return w | |
} | |
// Final using catch handle the error generated by a task. | |
func (w *ErrorWrapper) Final(catch func(error)) { | |
if w.err != nil { | |
catch(w.err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment