@@ -415,7 +415,15 @@ func NewDecoder(config *DecoderConfig) (*Decoder, error) {
415
415
// Decode decodes the given raw interface to the target pointer specified
416
416
// by the configuration.
417
417
func (d * Decoder ) Decode (input interface {}) error {
418
- return d .decode ("" , input , reflect .ValueOf (d .config .Result ).Elem ())
418
+ err := d .decode ("" , input , reflect .ValueOf (d .config .Result ).Elem ())
419
+
420
+ // Retain some of the original behavior when multiple errors ocurr
421
+ var joinedErr interface { Unwrap () []error }
422
+ if errors .As (err , & joinedErr ) {
423
+ return fmt .Errorf ("decoding failed due to the following error(s):\n \n %w" , err )
424
+ }
425
+
426
+ return err
419
427
}
420
428
421
429
// Decodes an unknown data type into a specific reflection value.
@@ -882,7 +890,7 @@ func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val refle
882
890
valElemType := valType .Elem ()
883
891
884
892
// Accumulate errors
885
- errors := make ([] string , 0 )
893
+ var errs [] error
886
894
887
895
// If the input data is empty, then we just match what the input data is.
888
896
if dataVal .Len () == 0 {
@@ -904,15 +912,15 @@ func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val refle
904
912
// First decode the key into the proper type
905
913
currentKey := reflect .Indirect (reflect .New (valKeyType ))
906
914
if err := d .decode (fieldName , k .Interface (), currentKey ); err != nil {
907
- errors = appendErrors ( errors , err )
915
+ errs = append ( errs , err )
908
916
continue
909
917
}
910
918
911
919
// Next decode the data into the proper type
912
920
v := dataVal .MapIndex (k ).Interface ()
913
921
currentVal := reflect .Indirect (reflect .New (valElemType ))
914
922
if err := d .decode (fieldName , v , currentVal ); err != nil {
915
- errors = appendErrors ( errors , err )
923
+ errs = append ( errs , err )
916
924
continue
917
925
}
918
926
@@ -922,12 +930,7 @@ func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val refle
922
930
// Set the built up map to the value
923
931
val .Set (valMap )
924
932
925
- // If we had errors, return those
926
- if len (errors ) > 0 {
927
- return & joinedError {errors }
928
- }
929
-
930
- return nil
933
+ return errors .Join (errs ... )
931
934
}
932
935
933
936
func (d * Decoder ) decodeMapFromStruct (name string , dataVal reflect.Value , val reflect.Value , valMap reflect.Value ) error {
@@ -1165,7 +1168,7 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
1165
1168
}
1166
1169
1167
1170
// Accumulate any errors
1168
- errors := make ([] string , 0 )
1171
+ var errs [] error
1169
1172
1170
1173
for i := 0 ; i < dataVal .Len (); i ++ {
1171
1174
currentData := dataVal .Index (i ).Interface ()
@@ -1176,19 +1179,14 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
1176
1179
1177
1180
fieldName := name + "[" + strconv .Itoa (i ) + "]"
1178
1181
if err := d .decode (fieldName , currentData , currentField ); err != nil {
1179
- errors = appendErrors ( errors , err )
1182
+ errs = append ( errs , err )
1180
1183
}
1181
1184
}
1182
1185
1183
1186
// Finally, set the value to the slice we built up
1184
1187
val .Set (valSlice )
1185
1188
1186
- // If there were errors, we return those
1187
- if len (errors ) > 0 {
1188
- return & joinedError {errors }
1189
- }
1190
-
1191
- return nil
1189
+ return errors .Join (errs ... )
1192
1190
}
1193
1191
1194
1192
func (d * Decoder ) decodeArray (name string , data interface {}, val reflect.Value ) error {
@@ -1234,27 +1232,22 @@ func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value)
1234
1232
}
1235
1233
1236
1234
// Accumulate any errors
1237
- errors := make ([] string , 0 )
1235
+ var errs [] error
1238
1236
1239
1237
for i := 0 ; i < dataVal .Len (); i ++ {
1240
1238
currentData := dataVal .Index (i ).Interface ()
1241
1239
currentField := valArray .Index (i )
1242
1240
1243
1241
fieldName := name + "[" + strconv .Itoa (i ) + "]"
1244
1242
if err := d .decode (fieldName , currentData , currentField ); err != nil {
1245
- errors = appendErrors ( errors , err )
1243
+ errs = append ( errs , err )
1246
1244
}
1247
1245
}
1248
1246
1249
1247
// Finally, set the value to the array we built up
1250
1248
val .Set (valArray )
1251
1249
1252
- // If there were errors, we return those
1253
- if len (errors ) > 0 {
1254
- return & joinedError {errors }
1255
- }
1256
-
1257
- return nil
1250
+ return errors .Join (errs ... )
1258
1251
}
1259
1252
1260
1253
func (d * Decoder ) decodeStruct (name string , data interface {}, val reflect.Value ) error {
@@ -1316,7 +1309,8 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
1316
1309
}
1317
1310
1318
1311
targetValKeysUnused := make (map [interface {}]struct {})
1319
- errors := make ([]string , 0 )
1312
+
1313
+ var errs []error
1320
1314
1321
1315
// This slice will keep track of all the structs we'll be decoding.
1322
1316
// There can be more than one struct if there are embedded structs
@@ -1370,8 +1364,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
1370
1364
1371
1365
if squash {
1372
1366
if fieldVal .Kind () != reflect .Struct {
1373
- errors = appendErrors (errors ,
1374
- fmt .Errorf ("%s: unsupported type for squash: %s" , fieldType .Name , fieldVal .Kind ()))
1367
+ errs = append (errs , fmt .Errorf ("%s: unsupported type for squash: %s" , fieldType .Name , fieldVal .Kind ()))
1375
1368
} else {
1376
1369
structs = append (structs , fieldVal )
1377
1370
}
@@ -1450,7 +1443,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
1450
1443
}
1451
1444
1452
1445
if err := d .decode (fieldName , rawMapVal .Interface (), fieldValue ); err != nil {
1453
- errors = appendErrors ( errors , err )
1446
+ errs = append ( errs , err )
1454
1447
}
1455
1448
}
1456
1449
@@ -1465,7 +1458,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
1465
1458
1466
1459
// Decode it as-if we were just decoding this map onto our map.
1467
1460
if err := d .decodeMap (name , remain , remainField .val ); err != nil {
1468
- errors = appendErrors ( errors , err )
1461
+ errs = append ( errs , err )
1469
1462
}
1470
1463
1471
1464
// Set the map to nil so we have none so that the next check will
@@ -1481,7 +1474,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
1481
1474
sort .Strings (keys )
1482
1475
1483
1476
err := fmt .Errorf ("'%s' has invalid keys: %s" , name , strings .Join (keys , ", " ))
1484
- errors = appendErrors ( errors , err )
1477
+ errs = append ( errs , err )
1485
1478
}
1486
1479
1487
1480
if d .config .ErrorUnset && len (targetValKeysUnused ) > 0 {
@@ -1492,11 +1485,11 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
1492
1485
sort .Strings (keys )
1493
1486
1494
1487
err := fmt .Errorf ("'%s' has unset fields: %s" , name , strings .Join (keys , ", " ))
1495
- errors = appendErrors ( errors , err )
1488
+ errs = append ( errs , err )
1496
1489
}
1497
1490
1498
- if len ( errors ) > 0 {
1499
- return & joinedError { errors }
1491
+ if err := errors . Join ( errs ... ); err != nil {
1492
+ return err
1500
1493
}
1501
1494
1502
1495
// Add the unused keys to the list of unused keys if we're tracking metadata
0 commit comments