Skip to content

Commit a95b98c

Browse files
committed
Add error message string matchers
1 parent d8edf98 commit a95b98c

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

matchers.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package errors
2+
3+
import "strings"
4+
5+
// HasMessage reports whether any error in err's chain matches msg. It performs a case-insensitive matching.
6+
//
7+
// This is helpful when the error type's in err's chain is unknown and a string matching is preferred.
8+
func HasMessage(err error, msg string) bool {
9+
errs := Flatten(err)
10+
11+
for _, e := range errs {
12+
if strings.EqualFold(e.Msg, msg) {
13+
return true
14+
}
15+
}
16+
17+
return false
18+
}
19+
20+
// ContainsMessage reports whether any error in err's chain contains msg. It performs a case-insensitive matching.
21+
//
22+
// This is helpful when the error type's in err's chain is unknown and a string matching is preferred.
23+
func ContainsMessage(err error, msg string) bool {
24+
errs := Flatten(err)
25+
lowerMsg := strings.ToLower(msg)
26+
27+
for _, e := range errs {
28+
if strings.Contains(strings.ToLower(e.Msg), lowerMsg) {
29+
return true
30+
}
31+
}
32+
33+
return false
34+
}

matchers_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package errors
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestMatchers(t *testing.T) {
8+
t.Run("it should match message", itShouldMatchMessage)
9+
t.Run("it should match containing message", itShouldMatchContainingMessage)
10+
}
11+
12+
func itShouldMatchMessage(t *testing.T) {
13+
err1 := E("this is an error", WithMeta("key1", "val1"))
14+
err2 := E("this is error2", err1, WithMeta("key2", "val2"))
15+
16+
has := HasMessage(err2, "this is an error")
17+
if has == false {
18+
t.Fatalf("HasMessage() return expected true, got false")
19+
}
20+
21+
has = HasMessage(err1, "this is an error")
22+
if has == false {
23+
t.Fatalf("HasMessage() should match a single err chain")
24+
}
25+
26+
has = HasMessage(err2, "this is error2")
27+
if has == false {
28+
t.Fatalf("HasMessage() should match the top-most wrapped error in the chain")
29+
}
30+
31+
has = HasMessage(err2, "ThIs Is An ErRor")
32+
if has == false {
33+
t.Fatalf("HasMessage() match should be case-insensitive")
34+
}
35+
36+
has = HasMessage(err2, "error2")
37+
if has == true {
38+
t.Fatalf("HasMessage() should match exact messages")
39+
}
40+
}
41+
42+
func itShouldMatchContainingMessage(t *testing.T) {
43+
err1 := E("this is an error", WithMeta("key1", "val1"))
44+
err2 := E("this is error2", err1, WithMeta("key2", "val2"))
45+
46+
has := ContainsMessage(err2, "an error")
47+
if has == false {
48+
t.Fatalf("ContainsMessage() should match partial messages")
49+
}
50+
51+
has = ContainsMessage(err2, "an erROR")
52+
if has == false {
53+
t.Fatalf("ContainsMessage() should match case-insensitive partial messages")
54+
}
55+
56+
has = ContainsMessage(err1, "an erROR")
57+
if has == false {
58+
t.Fatalf("ContainsMessage() should match a single err chain")
59+
}
60+
61+
has = ContainsMessage(err2, "erROR2")
62+
if has == false {
63+
t.Fatalf("ContainsMessage() should match the top-most wrapped error in the chain")
64+
}
65+
}

0 commit comments

Comments
 (0)