Codebase list golang-raven-go / HEAD errors_test.go
HEAD

Tree @HEAD (Download .tar.gz)

errors_test.go @HEADraw · history · blame

package raven

import (
	"fmt"
	"reflect"
	"testing"

	pkgErrors "github.com/pkg/errors"
)

func TestWrapWithExtraGeneratesProperErrWithExtra(t *testing.T) {
	errMsg := "This is bad"
	baseErr := fmt.Errorf(errMsg)
	extraInfo := map[string]interface{}{
		"string": "string",
		"int":    1,
		"float":  1.001,
		"bool":   false,
	}

	testErr := WrapWithExtra(baseErr, extraInfo)
	wrapped, ok := testErr.(ErrWithExtra)
	if !ok {
		t.Errorf("Wrapped error does not conform to expected protocol.")
	}

	if !reflect.DeepEqual(wrapped.Cause(), baseErr) {
		t.Errorf("Failed to unwrap error, got %+v, expected %+v", wrapped.Cause(), baseErr)
	}

	returnedExtra := wrapped.ExtraInfo()
	for expectedKey, expectedVal := range extraInfo {
		val, ok := returnedExtra[expectedKey]
		if !ok {
			t.Errorf("Extra data missing key: %s", expectedKey)
		}
		if val != expectedVal {
			t.Errorf("Extra data [%s]: Got: %+v, expected: %+v", expectedKey, val, expectedVal)
		}
	}

	if wrapped.Error() != errMsg {
		t.Errorf("Wrong error message, got: %q, expected: %q", wrapped.Error(), errMsg)
	}
}

func TestWrapWithExtraGeneratesCausableError(t *testing.T) {
	baseErr := fmt.Errorf("this is bad")
	testErr := WrapWithExtra(baseErr, nil)
	cause := pkgErrors.Cause(testErr)

	if !reflect.DeepEqual(cause, baseErr) {
		t.Errorf("Failed to unwrap error, got %+v, expected %+v", cause, baseErr)
	}
}

func TestExtractErrorPullsExtraData(t *testing.T) {
	extraInfo := map[string]interface{}{
		"string": "string",
		"int":    1,
		"float":  1.001,
		"bool":   false,
	}
	emptyInfo := map[string]interface{}{}

	testCases := []struct {
		Error    error
		Expected map[string]interface{}
	}{
		// Unwrapped error shouldn't include anything
		{
			Error:    fmt.Errorf("This is bad"),
			Expected: emptyInfo,
		},
		// Wrapped error with nil map should extract as empty info
		{
			Error:    WrapWithExtra(fmt.Errorf("This is bad"), nil),
			Expected: emptyInfo,
		},
		// Wrapped error with empty map should extract as empty info
		{
			Error:    WrapWithExtra(fmt.Errorf("This is bad"), emptyInfo),
			Expected: emptyInfo,
		},
		// Wrapped error with extra info should extract with all data
		{
			Error:    WrapWithExtra(fmt.Errorf("This is bad"), extraInfo),
			Expected: extraInfo,
		},
		// Nested wrapped error should extract all the info
		{
			Error: WrapWithExtra(
				WrapWithExtra(fmt.Errorf("This is bad"),
					map[string]interface{}{
						"inner": "123",
					}),
				map[string]interface{}{
					"outer": "456",
				},
			),
			Expected: map[string]interface{}{
				"inner": "123",
				"outer": "456",
			},
		},
		// Futher wrapping of errors shouldn't allow for value override
		{
			Error: WrapWithExtra(
				WrapWithExtra(fmt.Errorf("This is bad"),
					map[string]interface{}{
						"dontoverride": "123",
					}),
				map[string]interface{}{
					"dontoverride": "456",
				},
			),
			Expected: map[string]interface{}{
				"dontoverride": "123",
			},
		},
	}

	for i, test := range testCases {
		extracted := extractExtra(test.Error)
		if len(test.Expected) != len(extracted) {
			t.Errorf(
				"Case [%d]: Mismatched amount of data between provided and extracted extra. Got: %+v Expected: %+v",
				i,
				extracted,
				test.Expected,
			)
		}

		for expectedKey, expectedVal := range test.Expected {
			val, ok := extracted[expectedKey]
			if !ok {
				t.Errorf("Case [%d]: Extra data missing key: %s", i, expectedKey)
			}
			if val != expectedVal {
				t.Errorf("Case [%d]: Wrong extra data for %q. Got: %+v, expected: %+v", i, expectedKey, val, expectedVal)
			}
		}
	}
}