Skip to content

Commit 420d19b

Browse files
committed
copy-on-write for error
1 parent 5f4a9e9 commit 420d19b

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

error.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,40 @@ var _ fmt.Formatter = (*Error)(nil)
2626
// It is a caller's responsibility to accumulate and update a property, if needed.
2727
// Dynamic properties is a brittle mechanism and should therefore be used with care and in a simple and robust manner.
2828
func (e *Error) WithProperty(key Property, value interface{}) *Error {
29-
if e.properties == nil {
30-
e.properties = make(map[Property]interface{}, 1)
29+
errorCopy := *e
30+
31+
if errorCopy.properties == nil {
32+
errorCopy.properties = make(map[Property]interface{}, 1)
33+
} else {
34+
errorCopy.properties = make(map[Property]interface{}, len(e.properties) + 1)
35+
for k, v := range e.properties {
36+
errorCopy.properties[k] = v
37+
}
3138
}
3239

33-
e.properties[key] = value
34-
return e
40+
errorCopy.properties[key] = value
41+
return &errorCopy
3542
}
3643

3744
// WithUnderlyingErrors adds multiple additional related (hidden, suppressed) errors to be used exclusively in error output.
3845
// Note that these errors make no other effect whatsoever: their traits, types, properties etc. are lost on the observer.
3946
// Consider using errorx.DecorateMany instead.
4047
func (e *Error) WithUnderlyingErrors(errs ...error) *Error {
48+
errorCopy := *e
49+
50+
newUnderying := make([]error, 0, len(e.underlying) + len(errs))
51+
newUnderying = append(newUnderying, e.underlying...)
52+
4153
for _, err := range errs {
4254
if err == nil {
4355
continue
4456
}
4557

46-
e.underlying = append(e.underlying, err)
58+
newUnderying = append(newUnderying, err)
4759
}
4860

49-
return e
61+
errorCopy.underlying = newUnderying
62+
return &errorCopy
5063
}
5164

5265
// Property extracts a dynamic property value from an error.

0 commit comments

Comments
 (0)