Last active
April 4, 2018 21:51
-
-
Save jecolasurdo/0c88fe3b771aa0de8c755277c8e9068c to your computer and use it in GitHub Desktop.
Must. A 30 minute rabbit hole of interesting non-performant and opaque code.
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
// Must executes the supplied function and panics if the function returns an error. | |
// | |
// In practice, this approach to forcing a panic should be avoided because it's non-performant, | |
// and does nothing to increase code clarity. But it was a fun little rabbit hole to wander down. | |
// It's also a nice little example of how to call a function via reflection. | |
// | |
// supported type for f is | |
// func(T) error | |
// where `T` is the underlaying type for `input` | |
// | |
// // example of a typical way of forcing a panic on an error | |
// describeLogGroupsInput := &cloudwatchlogs.DescribeLogGroupsInput{ | |
// LogGroupNamePrefix: &env.LogGroupName, | |
// } | |
// describeLogGroupsOutput, err := c.DescribeLogGroups(describeLogGroupsInput) | |
// if err != nil { | |
// panic(err) | |
// } | |
// | |
// // example of hiding the error handling with a call to Must | |
// describeLogGroupsInput := &cloudwatchlogs.DescribeLogGroupsInput{ | |
// LogGroupNamePrefix: &env.LogGroupName, | |
// } | |
// describeLogGroupsOutput := Must(c.DescribeLogGroups, describeLogGroupsInput).(cloudwatchlogs.DescribeLogGroupsOutput) | |
// | |
func Must(f, input interface{}) interface{} { | |
fnType := reflect.TypeOf(f) | |
if fnType.Kind() != reflect.Func { | |
panic("f must be a function") | |
} | |
if fnType.NumIn() != 1 { | |
panic("f must have exactly one input field") | |
} | |
if fnType.NumOut() != 1 { | |
panic("f must have exactly one output field") | |
} | |
if !fnType.Out(1).Implements(reflect.TypeOf(error(nil))) { | |
panic("f must output an error") | |
} | |
fn := reflect.ValueOf(f) | |
in := []reflect.Value{reflect.ValueOf(input)} | |
out := fn.Call(in) | |
if !out[1].IsNil() { | |
panic(out[1].Interface().(error)) | |
} | |
return out[0] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
PS: This code was never run. I have no idea if it even compiles.