diff --git a/context.go b/context.go index 1c76c0f6..a6b77075 100644 --- a/context.go +++ b/context.go @@ -140,6 +140,15 @@ func (c *Context) Copy() *Context { cp.Params = make([]Param, len(cParams)) copy(cp.Params, cParams) + cErrors := c.Errors + cp.Errors = make(errorMsgs, len(cErrors)) + for i, e := range cErrors { + cp.Errors[i] = &Error{ + Err: e.Err, + Type: e.Type, + Meta: e.Meta, + } + } return &cp } diff --git a/context_test.go b/context_test.go index ef0cfccd..2933f9b7 100644 --- a/context_test.go +++ b/context_test.go @@ -542,6 +542,41 @@ func TestContextCopy(t *testing.T) { assert.Equal(t, cp.fullPath, c.fullPath) } +func TestContextCopyErrors(t *testing.T) { + c, _ := CreateTestContext(httptest.NewRecorder()) + + // Add errors to the original context + c.Error(fmt.Errorf("first error")).SetType(ErrorTypePublic).SetMeta("meta1") // nolint: errcheck + c.Error(fmt.Errorf("second error")).SetType(ErrorTypePrivate).SetMeta(42) // nolint: errcheck + + // Copy the context + cp := c.Copy() + + // Verify the copied context has the same number of errors + assert.Equal(t, len(c.Errors), len(cp.Errors), "Copied context should have the same number of errors") + + // Verify that the slices are distinct (deep copy) by checking contents and ensuring independence + assert.True(t, reflect.DeepEqual(c.Errors, cp.Errors), "Copied errors should have the same content initially") + // Since we can’t compare slices with ==, we rely on content equality and test isolation below + + // Check each error in the copied context matches the original + for i, origErr := range c.Errors { + copiedErr := cp.Errors[i] + assert.Equal(t, origErr.Err, copiedErr.Err, "Error message should match") + assert.Equal(t, origErr.Type, copiedErr.Type, "Error type should match") + assert.Equal(t, origErr.Meta, copiedErr.Meta, "Error metadata should match") + // Ensure pointers are different (deep copy) + assert.NotSame(t, origErr, copiedErr, "Each error should be a distinct instance") + } + + // Modify original context errors and ensure copy remains unchanged + c.Error(fmt.Errorf("third error")) // nolint: errcheck + assert.Equal(t, 2, len(cp.Errors), "Copied context errors should not reflect changes to original") + assert.Equal(t, 3, len(c.Errors), "Original context should have new error") + assert.False(t, reflect.DeepEqual(c.Errors, cp.Errors), "Copied errors should differ after modification") +} + + func TestContextHandlerName(t *testing.T) { c, _ := CreateTestContext(httptest.NewRecorder()) c.handlers = HandlersChain{func(c *Context) {}, handlerNameTest}