Skip to content

Commit 55a1d77

Browse files
internal/event: include context cancel cause in event
The context cancel cause can be a great way to understand why a context was canceled.
1 parent db928d3 commit 55a1d77

File tree

5 files changed

+38
-12
lines changed

5 files changed

+38
-12
lines changed

internal/event/context.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ func WriteError(ctx context.Context, caller Op, e error, opt ...Option) {
196196
return
197197
}
198198
}
199-
ev, err := newError(caller, e, opt...)
199+
ev, err := newError(ctx, caller, e, opt...)
200200
if err != nil {
201201
eventer.logger.Error(fmt.Sprintf("%s: %v", op, err))
202202
eventer.logger.Error(fmt.Sprintf("%s: unable to create new error to write error: %v", op, e))

internal/event/event_error.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package event
55

66
import (
7+
"context"
78
"errors"
89
"fmt"
910
"reflect"
@@ -13,16 +14,17 @@ import (
1314
const errorVersion = "v0.1"
1415

1516
type err struct {
16-
Error string `json:"error"`
17-
ErrorFields error `json:"error_fields"`
18-
Id Id `json:"id,omitempty"`
19-
Version string `json:"version"`
20-
Op Op `json:"op,omitempty"`
21-
RequestInfo *RequestInfo `json:"request_info,omitempty"`
22-
Info map[string]any `json:"info,omitempty"`
17+
Error string `json:"error"`
18+
ErrorFields error `json:"error_fields"`
19+
Id Id `json:"id,omitempty"`
20+
Version string `json:"version"`
21+
Op Op `json:"op,omitempty"`
22+
RequestInfo *RequestInfo `json:"request_info,omitempty"`
23+
Info map[string]any `json:"info,omitempty"`
24+
ContextCause error `json:"cause,omitempty"`
2325
}
2426

25-
func newError(fromOperation Op, e error, opt ...Option) (*err, error) {
27+
func newError(ctx context.Context, fromOperation Op, e error, opt ...Option) (*err, error) {
2628
const op = "event.newError"
2729
if fromOperation == "" {
2830
return nil, fmt.Errorf("%s: missing operation: %w", op, ErrInvalidParameter)
@@ -53,6 +55,9 @@ func newError(fromOperation Op, e error, opt ...Option) (*err, error) {
5355
Error: e.Error(),
5456
ErrorFields: e,
5557
}
58+
if ctx != nil {
59+
newErr.ContextCause = context.Cause(ctx)
60+
}
5661
if err := newErr.validate(); err != nil {
5762
return nil, fmt.Errorf("%s: %w", op, err)
5863
}

internal/event/event_error_test.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
package event
55

66
import (
7+
"cmp"
8+
"context"
9+
"errors"
710
"fmt"
811
"testing"
912

@@ -14,12 +17,16 @@ import (
1417

1518
func Test_newError(t *testing.T) {
1619
t.Parallel()
20+
ctx := context.Background()
21+
canceledCtx, cancel := context.WithCancelCause(ctx)
22+
cancel(errors.New("test cancel"))
1723

1824
tests := []struct {
1925
name string
2026
fromOp Op
2127
e error
2228
opts []Option
29+
ctx context.Context
2330
want *err
2431
wantErrIs error
2532
wantErrContains string
@@ -87,11 +94,25 @@ func Test_newError(t *testing.T) {
8794
Info: map[string]any{"msg": "hello"},
8895
},
8996
},
97+
{
98+
name: "context-cause",
99+
ctx: canceledCtx,
100+
fromOp: Op("context-cause"),
101+
e: fmt.Errorf("%s: valid: %w", "context-cause", ErrInvalidParameter),
102+
want: &err{
103+
ErrorFields: fmt.Errorf("%s: valid: %w", "context-cause", ErrInvalidParameter),
104+
Error: "context-cause: valid: invalid parameter",
105+
Version: errorVersion,
106+
Op: Op("context-cause"),
107+
ContextCause: errors.New("test cancel"),
108+
},
109+
},
90110
}
91111
for _, tt := range tests {
92112
t.Run(tt.name, func(t *testing.T) {
93113
assert, require := assert.New(t), require.New(t)
94-
got, err := newError(tt.fromOp, tt.e, tt.opts...)
114+
testCtx := cmp.Or(tt.ctx, ctx)
115+
got, err := newError(testCtx, tt.fromOp, tt.e, tt.opts...)
95116
if tt.wantErrIs != nil {
96117
require.Error(err)
97118
assert.Nil(got)

internal/event/eventer_retry_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func TestEventer_retrySend(t *testing.T) {
3030
require.NoError(t, err)
3131

3232
testError := fmt.Errorf("%s: missing operation: %w", "missing operation", ErrInvalidParameter)
33-
testEvent, err := newError("TestEventer_retrySend", testError, WithId("test-error"))
33+
testEvent, err := newError(ctx, "TestEventer_retrySend", testError, WithId("test-error"))
3434
require.NoError(t, err)
3535

3636
tests := []struct {

internal/event/eventer_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ func TestEventer_writeError(t *testing.T) {
304304
eventer, er := NewEventer(testLogger, testLock, "TestEventer_writeError", testSetup.EventerConfig)
305305
require.NoError(t, er)
306306

307-
testError, er := newError("TestEventer_writeError", fmt.Errorf("%s: no msg: test", ErrIo))
307+
testError, er := newError(ctx, "TestEventer_writeError", fmt.Errorf("%s: no msg: test", ErrIo))
308308
require.NoError(t, er)
309309

310310
tests := []struct {

0 commit comments

Comments
 (0)