mirror of
https://github.com/samber/lo.git
synced 2026-04-22 23:47:11 +08:00
Add context to Must panic message (#140)
This commit is contained in:
@@ -1560,6 +1560,10 @@ val := lo.Must(time.Parse("2006-01-02", "2022-01-15"))
|
||||
|
||||
val := lo.Must(time.Parse("2006-01-02", "bad-value"))
|
||||
// panics
|
||||
|
||||
val := lo.Must(lo.Find(myString, func(i string) bool {
|
||||
return i == requiredChar
|
||||
}), "'%s' must always contain '%s'", myString, requiredChar)
|
||||
```
|
||||
|
||||
### Must{0->6}
|
||||
|
||||
@@ -1,62 +1,93 @@
|
||||
package lo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
|
||||
if len(msgAndArgs) == 1 {
|
||||
return fmt.Sprintf(msgAndArgs[0].(string))
|
||||
}
|
||||
if len(msgAndArgs) > 1 {
|
||||
return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// must panics if err is error or false.
|
||||
func must(err any) {
|
||||
b, isBool := err.(bool)
|
||||
if isBool && !b {
|
||||
panic("not ok")
|
||||
func must(err any, messageArgs ...interface{}) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
e, isError := err.(error)
|
||||
if isError {
|
||||
panic(e)
|
||||
message := messageFromMsgAndArgs(messageArgs...)
|
||||
|
||||
switch e := err.(type) {
|
||||
case bool:
|
||||
if !e {
|
||||
if message == "" {
|
||||
message = "not ok"
|
||||
}
|
||||
panic(message)
|
||||
}
|
||||
|
||||
case error:
|
||||
if message != "" {
|
||||
panic(message + ": " + e.Error())
|
||||
} else {
|
||||
panic(e.Error())
|
||||
}
|
||||
|
||||
default:
|
||||
panic("must: invalid err type '" + reflect.TypeOf(err).Name() + "', should either be a bool or an error")
|
||||
}
|
||||
}
|
||||
|
||||
// Must is a helper that wraps a call to a function returning a value and an error
|
||||
// and panics if err is error or false.
|
||||
func Must[T any](val T, err any) T {
|
||||
must(err)
|
||||
func Must[T any](val T, err any, messageArgs ...interface{}) T {
|
||||
must(err, messageArgs...)
|
||||
return val
|
||||
}
|
||||
|
||||
// Must0 has the same behavior than Must, but callback returns no variable.
|
||||
func Must0(err any) {
|
||||
must(err)
|
||||
func Must0(err any, messageArgs ...interface{}) {
|
||||
must(err, messageArgs...)
|
||||
}
|
||||
|
||||
// Must1 is an alias to Must
|
||||
func Must1[T any](val T, err any) T {
|
||||
return Must(val, err)
|
||||
func Must1[T any](val T, err any, messageArgs ...interface{}) T {
|
||||
return Must(val, err, messageArgs...)
|
||||
}
|
||||
|
||||
// Must2 has the same behavior than Must, but callback returns 2 variables.
|
||||
func Must2[T1 any, T2 any](val1 T1, val2 T2, err any) (T1, T2) {
|
||||
must(err)
|
||||
func Must2[T1 any, T2 any](val1 T1, val2 T2, err any, messageArgs ...interface{}) (T1, T2) {
|
||||
must(err, messageArgs...)
|
||||
return val1, val2
|
||||
}
|
||||
|
||||
// Must3 has the same behavior than Must, but callback returns 3 variables.
|
||||
func Must3[T1 any, T2 any, T3 any](val1 T1, val2 T2, val3 T3, err any) (T1, T2, T3) {
|
||||
must(err)
|
||||
func Must3[T1 any, T2 any, T3 any](val1 T1, val2 T2, val3 T3, err any, messageArgs ...interface{}) (T1, T2, T3) {
|
||||
must(err, messageArgs...)
|
||||
return val1, val2, val3
|
||||
}
|
||||
|
||||
// Must4 has the same behavior than Must, but callback returns 4 variables.
|
||||
func Must4[T1 any, T2 any, T3 any, T4 any](val1 T1, val2 T2, val3 T3, val4 T4, err any) (T1, T2, T3, T4) {
|
||||
must(err)
|
||||
func Must4[T1 any, T2 any, T3 any, T4 any](val1 T1, val2 T2, val3 T3, val4 T4, err any, messageArgs ...interface{}) (T1, T2, T3, T4) {
|
||||
must(err, messageArgs...)
|
||||
return val1, val2, val3, val4
|
||||
}
|
||||
|
||||
// Must5 has the same behavior than Must, but callback returns 5 variables.
|
||||
func Must5[T1 any, T2 any, T3 any, T4 any, T5 any](val1 T1, val2 T2, val3 T3, val4 T4, val5 T5, err any) (T1, T2, T3, T4, T5) {
|
||||
must(err)
|
||||
func Must5[T1 any, T2 any, T3 any, T4 any, T5 any](val1 T1, val2 T2, val3 T3, val4 T4, val5 T5, err any, messageArgs ...interface{}) (T1, T2, T3, T4, T5) {
|
||||
must(err, messageArgs...)
|
||||
return val1, val2, val3, val4, val5
|
||||
}
|
||||
|
||||
// Must6 has the same behavior than Must, but callback returns 6 variables.
|
||||
func Must6[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any](val1 T1, val2 T2, val3 T3, val4 T4, val5 T5, val6 T6, err any) (T1, T2, T3, T4, T5, T6) {
|
||||
must(err)
|
||||
func Must6[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any](val1 T1, val2 T2, val3 T3, val4 T4, val5 T5, val6 T6, err any, messageArgs ...interface{}) (T1, T2, T3, T4, T5, T6) {
|
||||
must(err, messageArgs...)
|
||||
return val1, val2, val3, val4, val5, val6
|
||||
}
|
||||
|
||||
|
||||
+65
-28
@@ -10,24 +10,40 @@ import (
|
||||
|
||||
func TestMust(t *testing.T) {
|
||||
is := assert.New(t)
|
||||
|
||||
is.Equal("foo", Must("foo", nil))
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("something went wrong", func() {
|
||||
Must("", errors.New("something went wrong"))
|
||||
})
|
||||
is.PanicsWithValue("operation shouldn't fail: something went wrong", func() {
|
||||
Must("", errors.New("something went wrong"), "operation shouldn't fail")
|
||||
})
|
||||
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
|
||||
Must("", errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
|
||||
is.Equal(1, Must(1, true))
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("not ok", func() {
|
||||
Must(1, false)
|
||||
})
|
||||
is.PanicsWithValue("operation shouldn't fail", func() {
|
||||
Must(1, false, "operation shouldn't fail")
|
||||
})
|
||||
is.PanicsWithValue("operation shouldn't fail with foo", func() {
|
||||
Must(1, false, "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
}
|
||||
|
||||
func TestMustX(t *testing.T) {
|
||||
is := assert.New(t)
|
||||
|
||||
{
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("something went wrong", func() {
|
||||
Must0(errors.New("something went wrong"))
|
||||
})
|
||||
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
|
||||
Must0(errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
is.NotPanics(func() {
|
||||
Must0(nil)
|
||||
})
|
||||
@@ -36,11 +52,11 @@ func TestMustX(t *testing.T) {
|
||||
{
|
||||
val1 := Must1(1, nil)
|
||||
is.Equal(1, val1)
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("something went wrong", func() {
|
||||
Must1(1, errors.New("something went wrong"))
|
||||
})
|
||||
is.NotPanics(func() {
|
||||
Must1(1, nil)
|
||||
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
|
||||
Must1(1, errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -48,11 +64,11 @@ func TestMustX(t *testing.T) {
|
||||
val1, val2 := Must2(1, 2, nil)
|
||||
is.Equal(1, val1)
|
||||
is.Equal(2, val2)
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("something went wrong", func() {
|
||||
Must2(1, 2, errors.New("something went wrong"))
|
||||
})
|
||||
is.NotPanics(func() {
|
||||
Must2(1, 2, nil)
|
||||
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
|
||||
Must2(1, 2, errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -61,11 +77,11 @@ func TestMustX(t *testing.T) {
|
||||
is.Equal(1, val1)
|
||||
is.Equal(2, val2)
|
||||
is.Equal(3, val3)
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("something went wrong", func() {
|
||||
Must3(1, 2, 3, errors.New("something went wrong"))
|
||||
})
|
||||
is.NotPanics(func() {
|
||||
Must3(1, 2, 3, nil)
|
||||
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
|
||||
Must3(1, 2, 3, errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -75,11 +91,11 @@ func TestMustX(t *testing.T) {
|
||||
is.Equal(2, val2)
|
||||
is.Equal(3, val3)
|
||||
is.Equal(4, val4)
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("something went wrong", func() {
|
||||
Must4(1, 2, 3, 4, errors.New("something went wrong"))
|
||||
})
|
||||
is.NotPanics(func() {
|
||||
Must4(1, 2, 3, 4, nil)
|
||||
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
|
||||
Must4(1, 2, 3, 4, errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -90,11 +106,11 @@ func TestMustX(t *testing.T) {
|
||||
is.Equal(3, val3)
|
||||
is.Equal(4, val4)
|
||||
is.Equal(5, val5)
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("something went wrong", func() {
|
||||
Must5(1, 2, 3, 4, 5, errors.New("something went wrong"))
|
||||
})
|
||||
is.NotPanics(func() {
|
||||
Must5(1, 2, 3, 4, 5, nil)
|
||||
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
|
||||
Must5(1, 2, 3, 4, 5, errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -106,18 +122,21 @@ func TestMustX(t *testing.T) {
|
||||
is.Equal(4, val4)
|
||||
is.Equal(5, val5)
|
||||
is.Equal(6, val6)
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("something went wrong", func() {
|
||||
Must6(1, 2, 3, 4, 5, 6, errors.New("something went wrong"))
|
||||
})
|
||||
is.NotPanics(func() {
|
||||
Must6(1, 2, 3, 4, 5, 6, nil)
|
||||
is.PanicsWithValue("operation shouldn't fail with foo: something went wrong", func() {
|
||||
Must6(1, 2, 3, 4, 5, 6, errors.New("something went wrong"), "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("not ok", func() {
|
||||
Must0(false)
|
||||
})
|
||||
is.PanicsWithValue("operation shouldn't fail with foo", func() {
|
||||
Must0(false, "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
is.NotPanics(func() {
|
||||
Must0(true)
|
||||
})
|
||||
@@ -126,18 +145,24 @@ func TestMustX(t *testing.T) {
|
||||
{
|
||||
val1 := Must1(1, true)
|
||||
is.Equal(1, val1)
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("not ok", func() {
|
||||
Must1(1, false)
|
||||
})
|
||||
is.PanicsWithValue("operation shouldn't fail with foo", func() {
|
||||
Must1(1, false, "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
val1, val2 := Must2(1, 2, true)
|
||||
is.Equal(1, val1)
|
||||
is.Equal(2, val2)
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("not ok", func() {
|
||||
Must2(1, 2, false)
|
||||
})
|
||||
is.PanicsWithValue("operation shouldn't fail with foo", func() {
|
||||
Must2(1, 2, false, "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
@@ -145,9 +170,12 @@ func TestMustX(t *testing.T) {
|
||||
is.Equal(1, val1)
|
||||
is.Equal(2, val2)
|
||||
is.Equal(3, val3)
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("not ok", func() {
|
||||
Must3(1, 2, 3, false)
|
||||
})
|
||||
is.PanicsWithValue("operation shouldn't fail with foo", func() {
|
||||
Must3(1, 2, 3, false, "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
@@ -156,9 +184,12 @@ func TestMustX(t *testing.T) {
|
||||
is.Equal(2, val2)
|
||||
is.Equal(3, val3)
|
||||
is.Equal(4, val4)
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("not ok", func() {
|
||||
Must4(1, 2, 3, 4, false)
|
||||
})
|
||||
is.PanicsWithValue("operation shouldn't fail with foo", func() {
|
||||
Must4(1, 2, 3, 4, false, "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
@@ -168,9 +199,12 @@ func TestMustX(t *testing.T) {
|
||||
is.Equal(3, val3)
|
||||
is.Equal(4, val4)
|
||||
is.Equal(5, val5)
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("not ok", func() {
|
||||
Must5(1, 2, 3, 4, 5, false)
|
||||
})
|
||||
is.PanicsWithValue("operation shouldn't fail with foo", func() {
|
||||
Must5(1, 2, 3, 4, 5, false, "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
@@ -181,9 +215,12 @@ func TestMustX(t *testing.T) {
|
||||
is.Equal(4, val4)
|
||||
is.Equal(5, val5)
|
||||
is.Equal(6, val6)
|
||||
is.Panics(func() {
|
||||
is.PanicsWithValue("not ok", func() {
|
||||
Must6(1, 2, 3, 4, 5, 6, false)
|
||||
})
|
||||
is.PanicsWithValue("operation shouldn't fail with foo", func() {
|
||||
Must6(1, 2, 3, 4, 5, 6, false, "operation shouldn't fail with %s", "foo")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user