Skip to content

Commit b163dcc

Browse files
committed
Make metadata type exported
Signed-off-by: Emruz Hossain <[email protected]>
1 parent 2e8b278 commit b163dcc

File tree

3 files changed

+15
-174
lines changed

3 files changed

+15
-174
lines changed

examples/errors/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func main() {
1919

2020
func someCodeProducesError() error {
2121
// root wrapper that include function name as context
22-
errMetadata := errhelper.Metadata("function", "someCodeProducesError")
22+
errMetadata := errhelper.Metadata{"function", "someCodeProducesError"}
2323

2424
// another block of code that can produce error
2525
err := doSomething()

pkg/errors/errors.go

+2-61
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,10 @@ func (w *errWithMetadata) Unwrap() error {
2727
return w.err
2828
}
2929

30-
type errorMetadata []string
31-
32-
// Metadata returns a new metadata container with the provided key value pairs
33-
func Metadata(keyValues ...string) errorMetadata {
34-
return keyValues
35-
}
30+
type Metadata []string
3631

3732
// Extend returns a new metadata container with combined key value pairs from current metadata and provided key value pairs
38-
func (m *errorMetadata) Extend(keyValues ...string) errorMetadata {
33+
func (m *Metadata) Extend(keyValues ...string) Metadata {
3934
if m == nil {
4035
return keyValues
4136
}
@@ -113,57 +108,3 @@ func addPaddingForMissingValue(keyValues []string) []string {
113108
}
114109
return newKV
115110
}
116-
117-
// nonRetryableError is a wrapper for errors that resulted from an operation that should not be retried
118-
type nonRetryableError struct {
119-
err error
120-
}
121-
122-
// Error returns the original error message,
123-
func (e *nonRetryableError) Error() string {
124-
return e.err.Error()
125-
}
126-
127-
// Unwrap returns the original error.
128-
// It allows the error to be compatible with standard error unwrapping mechanism
129-
func (e *nonRetryableError) Unwrap() error {
130-
return e.err
131-
}
132-
133-
// AsNonRetryableError wraps an error as non-retryable error
134-
func AsNonRetryableError(err error, metadata ...string) error {
135-
return &nonRetryableError{err: WithMetadata(err, metadata...)}
136-
}
137-
138-
// IsNonRetryableError checks if the error is a non-retryable or not
139-
func IsNonRetryableError(err error) bool {
140-
var e *nonRetryableError
141-
return errors.As(err, &e)
142-
}
143-
144-
// retryableError is a wrapper for errors that resulted from an operation that can be retried
145-
type retryableError struct {
146-
err error
147-
}
148-
149-
// Error returns the original error message,
150-
func (e *retryableError) Error() string {
151-
return e.err.Error()
152-
}
153-
154-
// Unwrap returns the original error.
155-
// It allows the error to be compatible with standard error unwrapping mechanism
156-
func (e *retryableError) Unwrap() error {
157-
return e.err
158-
}
159-
160-
// AsRetryableError wraps an error as retryable error
161-
func AsRetryableError(err error, metadata ...string) error {
162-
return &retryableError{err: WithMetadata(err, metadata...)}
163-
}
164-
165-
// IsRetryableError checks if the error is retryable or not
166-
func IsRetryableError(err error) bool {
167-
var e *retryableError
168-
return errors.As(err, &e)
169-
}

pkg/errors/errors_test.go

+12-112
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func TestError(t *testing.T) {
3939

4040
func TestErrWrapper_Extend(t *testing.T) {
4141
// create error context with some metadata
42-
errMeta := Metadata("k1", "v1")
42+
errMeta := Metadata{"k1", "v1"}
4343
// extend the error context with additional metadata
4444
extendedMetadata := errMeta.Extend("k2", "v2")
4545
// verify that the extended context contains both original and new metadata
@@ -50,15 +50,15 @@ func TestWithMetadata(t *testing.T) {
5050
fooError := errors.New("foo")
5151
testCases := []struct {
5252
name string
53-
curMetadata errorMetadata
53+
curMetadata Metadata
5454
newMetadata []string
5555
err error
5656
expected *errWithMetadata
5757
}{
5858
{
5959
name: "when error is nil",
6060
err: nil,
61-
curMetadata: errorMetadata{"k1", "v1"},
61+
curMetadata: Metadata{"k1", "v1"},
6262
newMetadata: []string{"k2", "v2"},
6363
expected: nil,
6464
},
@@ -75,7 +75,7 @@ func TestWithMetadata(t *testing.T) {
7575
{
7676
name: "when current metadata is empty",
7777
err: fooError,
78-
curMetadata: errorMetadata{},
78+
curMetadata: Metadata{},
7979
newMetadata: []string{"k2", "v2"},
8080
expected: &errWithMetadata{
8181
err: fooError,
@@ -85,7 +85,7 @@ func TestWithMetadata(t *testing.T) {
8585
{
8686
name: "when new metadata is nil",
8787
err: fooError,
88-
curMetadata: errorMetadata{"k1", "v1"},
88+
curMetadata: Metadata{"k1", "v1"},
8989
newMetadata: nil,
9090
expected: &errWithMetadata{
9191
err: fooError,
@@ -95,7 +95,7 @@ func TestWithMetadata(t *testing.T) {
9595
{
9696
name: "when new metadata is empty",
9797
err: fooError,
98-
curMetadata: errorMetadata{"k1", "v1"},
98+
curMetadata: Metadata{"k1", "v1"},
9999
newMetadata: []string{},
100100
expected: &errWithMetadata{
101101
err: fooError,
@@ -115,7 +115,7 @@ func TestWithMetadata(t *testing.T) {
115115
{
116116
name: "when both current and new metadata are not empty",
117117
err: fooError,
118-
curMetadata: errorMetadata{"k1", "v1"},
118+
curMetadata: Metadata{"k1", "v1"},
119119
newMetadata: []string{"k2", "v2"},
120120
expected: &errWithMetadata{
121121
err: fooError,
@@ -125,7 +125,7 @@ func TestWithMetadata(t *testing.T) {
125125
{
126126
name: "when current metadata misses a value",
127127
err: fooError,
128-
curMetadata: errorMetadata{"k1"},
128+
curMetadata: Metadata{"k1"},
129129
newMetadata: []string{"k2", "v2"},
130130
expected: &errWithMetadata{
131131
err: fooError,
@@ -135,7 +135,7 @@ func TestWithMetadata(t *testing.T) {
135135
{
136136
name: "when new metadata misses a value",
137137
err: fooError,
138-
curMetadata: errorMetadata{"k1", "v1"},
138+
curMetadata: Metadata{"k1", "v1"},
139139
newMetadata: []string{"k2"},
140140
expected: &errWithMetadata{
141141
err: fooError,
@@ -145,7 +145,7 @@ func TestWithMetadata(t *testing.T) {
145145
{
146146
name: "when both current and new metadata misses a value",
147147
err: fooError,
148-
curMetadata: errorMetadata{"k1"},
148+
curMetadata: Metadata{"k1"},
149149
newMetadata: []string{"k2"},
150150
expected: &errWithMetadata{
151151
err: fooError,
@@ -155,7 +155,7 @@ func TestWithMetadata(t *testing.T) {
155155
{
156156
name: "when provided error is already wrapped with metadata",
157157
err: WithMetadata(fooError, "k0", "v0"),
158-
curMetadata: errorMetadata{"k1", "v1"},
158+
curMetadata: Metadata{"k1", "v1"},
159159
newMetadata: []string{"k2", "v2"},
160160
expected: &errWithMetadata{
161161
err: WithMetadata(fooError, "k0", "v0"),
@@ -165,7 +165,7 @@ func TestWithMetadata(t *testing.T) {
165165
{
166166
name: "when provided error is already wrapped with custom message",
167167
err: fmt.Errorf("bar: %w", fooError),
168-
curMetadata: errorMetadata{"k1", "v1"},
168+
curMetadata: Metadata{"k1", "v1"},
169169
newMetadata: []string{"k2", "v2"},
170170
expected: &errWithMetadata{
171171
err: fmt.Errorf("bar: %w", fooError),
@@ -299,103 +299,3 @@ func TestGetMetadata(t *testing.T) {
299299
})
300300
}
301301
}
302-
303-
func TestIsNonRetryableError(t *testing.T) {
304-
testCases := []struct {
305-
name string
306-
err error
307-
isNonRetryable bool
308-
}{
309-
{
310-
name: "error without wrapping",
311-
err: errors.New("foo"),
312-
isNonRetryable: false,
313-
},
314-
{
315-
name: "error wrapped with message",
316-
err: fmt.Errorf("foo: %w", errors.New("bar")),
317-
isNonRetryable: false,
318-
},
319-
{
320-
name: "error wrapped with metadata",
321-
err: WithMetadata(errors.New("foo"), "key", "value"),
322-
isNonRetryable: false,
323-
},
324-
{
325-
name: "non-retryable error wrapped with metadata",
326-
err: AsNonRetryableError(errors.New("foo"), "key", "value"),
327-
isNonRetryable: true,
328-
},
329-
{
330-
name: "non-retryable error without wrapping",
331-
err: &nonRetryableError{err: errors.New("foo")},
332-
isNonRetryable: true,
333-
},
334-
{
335-
name: "non-retryable error in the error chain",
336-
err: fmt.Errorf("foo: %w", &nonRetryableError{err: errors.New("bar")}),
337-
isNonRetryable: true,
338-
},
339-
{
340-
name: "retryable error",
341-
err: &retryableError{err: errors.New("foo")},
342-
isNonRetryable: false,
343-
},
344-
}
345-
346-
for _, tc := range testCases {
347-
t.Run(tc.name, func(t *testing.T) {
348-
require.Equal(t, tc.isNonRetryable, IsNonRetryableError(tc.err))
349-
})
350-
}
351-
}
352-
353-
func TestIsRetryableError(t *testing.T) {
354-
testCases := []struct {
355-
name string
356-
err error
357-
isRetryable bool
358-
}{
359-
{
360-
name: "error without wrapping",
361-
err: errors.New("foo"),
362-
isRetryable: false,
363-
},
364-
{
365-
name: "error wrapped with message",
366-
err: fmt.Errorf("foo: %w", errors.New("bar")),
367-
isRetryable: false,
368-
},
369-
{
370-
name: "error wrapped with metadata",
371-
err: WithMetadata(errors.New("foo"), "key", "value"),
372-
isRetryable: false,
373-
},
374-
{
375-
name: "retryable error wrapped with metadata",
376-
err: AsRetryableError(errors.New("foo"), "key", "value"),
377-
isRetryable: true,
378-
},
379-
{
380-
name: "retryable error without wrapping",
381-
err: &retryableError{err: errors.New("foo")},
382-
isRetryable: true,
383-
},
384-
{
385-
name: "retryable error in the error chain",
386-
err: fmt.Errorf("foo: %w", &retryableError{err: errors.New("bar")}),
387-
isRetryable: true,
388-
},
389-
{
390-
name: "non-retryable error",
391-
err: &nonRetryableError{err: errors.New("foo")},
392-
isRetryable: false,
393-
},
394-
}
395-
396-
for _, tc := range testCases {
397-
t.Run(tc.name, func(t *testing.T) {
398-
require.Equal(t, tc.isRetryable, IsRetryableError(tc.err))
399-
})
400-
}
401-
}

0 commit comments

Comments
 (0)