error_test.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Copyright (c) 2017 Uber Technologies, Inc.
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE.
  20. package zap
  21. import (
  22. "errors"
  23. "testing"
  24. "go.uber.org/zap/zapcore"
  25. richErrors "github.com/pkg/errors"
  26. "github.com/stretchr/testify/assert"
  27. "github.com/stretchr/testify/require"
  28. )
  29. func TestErrorConstructors(t *testing.T) {
  30. fail := errors.New("fail")
  31. tests := []struct {
  32. name string
  33. field Field
  34. expect Field
  35. }{
  36. {"Error", Skip(), Error(nil)},
  37. {"Error", Field{Key: "error", Type: zapcore.ErrorType, Interface: fail}, Error(fail)},
  38. {"NamedError", Skip(), NamedError("foo", nil)},
  39. {"NamedError", Field{Key: "foo", Type: zapcore.ErrorType, Interface: fail}, NamedError("foo", fail)},
  40. {"Any:Error", Any("k", errors.New("v")), NamedError("k", errors.New("v"))},
  41. {"Any:Errors", Any("k", []error{errors.New("v")}), Errors("k", []error{errors.New("v")})},
  42. }
  43. for _, tt := range tests {
  44. if !assert.Equal(t, tt.expect, tt.field, "Unexpected output from convenience field constructor %s.", tt.name) {
  45. t.Logf("type expected: %T\nGot: %T", tt.expect.Interface, tt.field.Interface)
  46. }
  47. assertCanBeReused(t, tt.field)
  48. }
  49. }
  50. func TestErrorArrayConstructor(t *testing.T) {
  51. tests := []struct {
  52. desc string
  53. field Field
  54. expected []interface{}
  55. }{
  56. {"empty errors", Errors("", []error{}), []interface{}{}},
  57. {
  58. "errors",
  59. Errors("", []error{nil, errors.New("foo"), nil, errors.New("bar")}),
  60. []interface{}{map[string]interface{}{"error": "foo"}, map[string]interface{}{"error": "bar"}},
  61. },
  62. }
  63. for _, tt := range tests {
  64. enc := zapcore.NewMapObjectEncoder()
  65. tt.field.Key = "k"
  66. tt.field.AddTo(enc)
  67. assert.Equal(t, tt.expected, enc.Fields["k"], "%s: unexpected map contents.", tt.desc)
  68. assert.Equal(t, 1, len(enc.Fields), "%s: found extra keys in map: %v", tt.desc, enc.Fields)
  69. }
  70. }
  71. func TestErrorsArraysHandleRichErrors(t *testing.T) {
  72. errs := []error{richErrors.New("egad")}
  73. enc := zapcore.NewMapObjectEncoder()
  74. Errors("k", errs).AddTo(enc)
  75. assert.Equal(t, 1, len(enc.Fields), "Expected only top-level field.")
  76. val := enc.Fields["k"]
  77. arr, ok := val.([]interface{})
  78. require.True(t, ok, "Expected top-level field to be an array.")
  79. require.Equal(t, 1, len(arr), "Expected only one error object in array.")
  80. serialized := arr[0]
  81. errMap, ok := serialized.(map[string]interface{})
  82. require.True(t, ok, "Expected serialized error to be a map, got %T.", serialized)
  83. assert.Equal(t, "egad", errMap["error"], "Unexpected standard error string.")
  84. assert.Contains(t, errMap["errorVerbose"], "egad", "Verbose error string should be a superset of standard error.")
  85. assert.Contains(t, errMap["errorVerbose"], "TestErrorsArraysHandleRichErrors", "Verbose error string should contain a stacktrace.")
  86. }