@@ -69,7 +69,25 @@ func As[T any](err error) (T, bool) {
6969 return t , true
7070 }
7171 }
72- err = Unwrap (err )
72+ switch x := err .(type ) {
73+ case interface { Unwrap () error }:
74+ err = x .Unwrap ()
75+ if err == nil {
76+ var z T
77+ return z , false
78+ }
79+ case interface { Unwrap () []error }:
80+ for _ , err := range x .Unwrap () {
81+ if t , ok := As [T ](err ); ok {
82+ return t , ok
83+ }
84+ }
85+ var z T
86+ return z , false
87+ default :
88+ var z T
89+ return z , false
90+ }
7391 }
7492
7593 var z T
@@ -106,8 +124,8 @@ func Errorf(message string, argsAndOptions ...interface{}) error {
106124 opts := newOptions (options ... )
107125 err := fmt .Errorf (message , args ... )
108126
109- argError := getArgError (message , args )
110- if isWrapper (argError ) {
127+ argErrors := getArgErrors (message , args )
128+ if len ( argErrors ) == 1 && isWrapper (argErrors [ 0 ] ) {
111129 return & wrapped {wrapped : err , fields : opts .fields }
112130 }
113131
@@ -126,12 +144,16 @@ func Wrap(err error, options ...Option) error {
126144 if err == nil {
127145 return nil
128146 }
129- opts := newOptions (options ... )
130-
131147 if isWrapper (err ) {
132- return & wrapped {wrapped : err , fields : opts .fields }
148+ if len (options ) == 0 {
149+ return err
150+ }
151+
152+ return & wrapped {wrapped : err , fields : newOptions (options ... ).fields }
133153 }
134154
155+ opts := newOptions (options ... )
156+
135157 return & stacked {
136158 wrapped : & wrapped {wrapped : err , fields : opts .fields },
137159 stack : newStack (opts .skipCallers ),
@@ -230,7 +252,13 @@ func (e *stacked) Format(s fmt.State, verb rune) {
230252func (e * stacked ) MarshalJSON () ([]byte , error ) {
231253 data := mapWriter {"error" : e .Error ()}
232254 data .SetStackTrace (e .StackTrace ())
233- e .LogFields (data )
255+
256+ var err error
257+ for err = e ; err != nil ; err = Unwrap (err ) {
258+ if loggable , ok := err .(LoggableError ); ok {
259+ loggable .LogFields (data )
260+ }
261+ }
234262
235263 return json .Marshal (data )
236264}
@@ -254,28 +282,30 @@ func splitArgsAndOptions(argsAndOptions []interface{}) ([]interface{}, []Option)
254282 return args , options
255283}
256284
257- func getArgError (message string , args []interface {}) error {
258- index := getErrorIndex (message )
285+ func getArgErrors (message string , args []interface {}) []error {
286+ indices := getErrorIndices (message )
287+ errs := make ([]error , 0 , len (indices ))
259288
260- if index >= 0 && index < len ( args ) {
261- if err , ok := args [index ].(error ); ok {
262- return err
289+ for _ , i := range indices {
290+ if err , ok := args [i ].(error ); ok {
291+ errs = append ( errs , err )
263292 }
264293 }
265294
266- return nil
295+ return errs
267296}
268297
269- func getErrorIndex (message string ) int {
270- i := - 1
298+ func getErrorIndices (message string ) [] int {
299+ indices := make ([] int , 0 , 1 )
271300 isFormat := false
272301
302+ i := - 1
273303 for _ , s := range message {
274304 if isFormat {
275305 if s != '%' {
276306 i ++
277307 if s == 'w' {
278- return i
308+ indices = append ( indices , i )
279309 }
280310 }
281311 isFormat = false
@@ -284,7 +314,7 @@ func getErrorIndex(message string) int {
284314 }
285315 }
286316
287- return - 1
317+ return indices
288318}
289319
290320type mapWriter map [string ]interface {}
0 commit comments