errors_test.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. package errors
  2. import (
  3. "fmt"
  4. "testing"
  5. "github.com/stretchr/testify/require"
  6. )
  7. func TestNew(t *testing.T) {
  8. t.Run("new error", func(t *testing.T) {
  9. err := New("hello")
  10. require.Equal(t, "hello", err.Message)
  11. require.Equal(t, "errors_test.go:12", err.Line)
  12. t.Log(err)
  13. })
  14. t.Run("new error with format", func(t *testing.T) {
  15. err := Newf("hello %v", 42)
  16. require.Equal(t, "hello 42", err.Message)
  17. require.Equal(t, "errors_test.go:19", err.Line)
  18. t.Log(err)
  19. })
  20. }
  21. func TestUnwrap(t *testing.T) {
  22. t.Run("enriched error is unwraped", func(t *testing.T) {
  23. werr := fmt.Errorf("werr")
  24. err := New("err").Wrap(werr)
  25. require.Equal(t, werr, Unwrap(err))
  26. })
  27. t.Run("enriched error is not unwraped", func(t *testing.T) {
  28. err := New("err")
  29. require.Nil(t, Unwrap(err))
  30. })
  31. }
  32. func TestIs(t *testing.T) {
  33. t.Run("is enriched error is true", func(t *testing.T) {
  34. err := New("test")
  35. require.True(t, Is(err, err))
  36. })
  37. t.Run("is enriched error is false", func(t *testing.T) {
  38. err := New("test")
  39. require.False(t, Is(err, New("test b")))
  40. })
  41. t.Run("is nested enriched error is true", func(t *testing.T) {
  42. werr := New("werr")
  43. err := fmt.Errorf("err: %w", werr)
  44. require.True(t, Is(err, werr))
  45. })
  46. t.Run("is nested enriched error is false", func(t *testing.T) {
  47. werr := New("werr")
  48. err := fmt.Errorf("err: %w", New("werr"))
  49. require.False(t, Is(err, werr))
  50. })
  51. t.Run("is not enriched nested error is true", func(t *testing.T) {
  52. werr := fmt.Errorf("werr")
  53. err := New("err").Wrap(werr)
  54. require.True(t, Is(err, werr))
  55. })
  56. t.Run("is not enriched nested error is false", func(t *testing.T) {
  57. werr := fmt.Errorf("werr")
  58. err := New("err").Wrap(fmt.Errorf("werr"))
  59. require.False(t, Is(err, werr))
  60. })
  61. }
  62. func TestAs(t *testing.T) {
  63. t.Run("has enriched error is true", func(t *testing.T) {
  64. var ierr Error
  65. err := New("err")
  66. require.True(t, As(err, &ierr))
  67. })
  68. t.Run("has not enriched error is false", func(t *testing.T) {
  69. var ierr Error
  70. err := fmt.Errorf("err")
  71. require.False(t, As(err, &ierr))
  72. })
  73. t.Run("has nested enriched error is true", func(t *testing.T) {
  74. var ierr Error
  75. err := fmt.Errorf("err: %w", New("werr"))
  76. require.True(t, As(err, &ierr))
  77. })
  78. }
  79. func TestHasType(t *testing.T) {
  80. t.Run("nil error is empty", func(t *testing.T) {
  81. require.True(t, HasType(nil, ""))
  82. })
  83. t.Run("enriched error is of the default type", func(t *testing.T) {
  84. err := New("err")
  85. require.True(t, HasType(err, "errors.Error"))
  86. })
  87. t.Run("enriched error is of the defined type", func(t *testing.T) {
  88. err := New("err").WithType("foo")
  89. require.True(t, HasType(err, "foo"))
  90. })
  91. t.Run("enriched error is not of the requested type", func(t *testing.T) {
  92. err := New("err").WithType("foo")
  93. require.False(t, HasType(err, "bar"))
  94. })
  95. t.Run("non enriched error is of the default type", func(t *testing.T) {
  96. err := fmt.Errorf("err")
  97. require.True(t, HasType(err, "*errors.errorString"))
  98. })
  99. t.Run("non enriched error is not of the requested type", func(t *testing.T) {
  100. err := fmt.Errorf("err")
  101. require.False(t, HasType(err, "foo"))
  102. })
  103. t.Run("enriched error is of the nested enriched type", func(t *testing.T) {
  104. err := New("err").Wrap(New("werr").WithType("foo"))
  105. require.True(t, HasType(err, "foo"))
  106. })
  107. t.Run("enriched error is of the nested non enriched type", func(t *testing.T) {
  108. err := New("err").Wrap(fmt.Errorf("werr"))
  109. require.True(t, HasType(err, "*errors.errorString"))
  110. })
  111. t.Run("non enriched error is of the nested enriched type", func(t *testing.T) {
  112. err := fmt.Errorf("err: %w", New("werr").WithType("foo"))
  113. require.True(t, HasType(err, "foo"))
  114. })
  115. }
  116. func TestTag(t *testing.T) {
  117. t.Run("enriched error returns the tag value", func(t *testing.T) {
  118. err := New("test").WithTag("foo", "bar")
  119. require.Equal(t, "bar", Tag(err, "foo"))
  120. })
  121. t.Run("enriched error does not returns the tag value", func(t *testing.T) {
  122. err := New("test")
  123. require.Empty(t, Tag(err, "foo"))
  124. })
  125. t.Run("nested enriched error in enriched error returns the tag value", func(t *testing.T) {
  126. err := New("err").Wrap(New("werr").WithTag("foo", "bar"))
  127. require.Equal(t, "bar", Tag(err, "foo"))
  128. })
  129. t.Run("nested enriched error in non enriched error returns the tag value", func(t *testing.T) {
  130. err := fmt.Errorf("err: %w", New("werr").WithTag("foo", "bar"))
  131. require.Equal(t, "bar", Tag(err, "foo"))
  132. })
  133. t.Run("non enriched error does not returns the tag value", func(t *testing.T) {
  134. err := fmt.Errorf("err")
  135. require.Empty(t, Tag(err, "foo"))
  136. })
  137. }
  138. func TestError(t *testing.T) {
  139. SetIndentEncoder()
  140. defer SetInlineEncoder()
  141. t.Run("stringify an enriched error", func(t *testing.T) {
  142. err := New("err").
  143. WithTag("foo", "bar").
  144. Error()
  145. require.Contains(t, err, "err")
  146. t.Log(err)
  147. })
  148. t.Run("stringify an enriched error wrapped in an enriched error", func(t *testing.T) {
  149. err := New("err").
  150. WithTag("foo", "bar").
  151. Wrap(New("werr").WithType("boo")).
  152. Error()
  153. require.Contains(t, err, "err")
  154. require.Contains(t, err, "werr")
  155. require.Contains(t, err, "boo")
  156. t.Log(err)
  157. })
  158. t.Run("stringify a non enriched error wrapped in an enriched error", func(t *testing.T) {
  159. err := New("err").
  160. WithTag("foo", "bar").
  161. Wrap(fmt.Errorf("werr")).
  162. Error()
  163. require.Contains(t, err, "err")
  164. require.Contains(t, err, "werr")
  165. t.Log(err)
  166. })
  167. t.Run("stringify a non enriched error wrapped in an enriched error", func(t *testing.T) {
  168. err := fmt.Errorf("err: %w", New("werr")).Error()
  169. require.Contains(t, err, "werr")
  170. require.NotContains(t, err, "*errors.errorString")
  171. require.Contains(t, err, "err")
  172. t.Log(err)
  173. })
  174. t.Run("stringify an enriched error with a bad tag", func(t *testing.T) {
  175. err := New("err").WithTag("func", func() {}).Error()
  176. require.Contains(t, err, "encoding error failed")
  177. t.Log(err)
  178. })
  179. }