@@ -160,12 +160,13 @@ package mapstructure
160160
161161import (
162162 "encoding/json"
163- "errors"
164163 "fmt"
165164 "reflect"
166165 "sort"
167166 "strconv"
168167 "strings"
168+
169+ "github.com/go-viper/mapstructure/v2/internal/errors"
169170)
170171
171172// DecodeHookFunc is the callback function that can be used for
@@ -414,7 +415,15 @@ func NewDecoder(config *DecoderConfig) (*Decoder, error) {
414415// Decode decodes the given raw interface to the target pointer specified
415416// by the configuration.
416417func (d * Decoder ) Decode (input interface {}) error {
417- 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
418427}
419428
420429// Decodes an unknown data type into a specific reflection value.
@@ -881,7 +890,7 @@ func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val refle
881890 valElemType := valType .Elem ()
882891
883892 // Accumulate errors
884- errors := make ([] string , 0 )
893+ var errs [] error
885894
886895 // If the input data is empty, then we just match what the input data is.
887896 if dataVal .Len () == 0 {
@@ -903,15 +912,15 @@ func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val refle
903912 // First decode the key into the proper type
904913 currentKey := reflect .Indirect (reflect .New (valKeyType ))
905914 if err := d .decode (fieldName , k .Interface (), currentKey ); err != nil {
906- errors = appendErrors ( errors , err )
915+ errs = append ( errs , err )
907916 continue
908917 }
909918
910919 // Next decode the data into the proper type
911920 v := dataVal .MapIndex (k ).Interface ()
912921 currentVal := reflect .Indirect (reflect .New (valElemType ))
913922 if err := d .decode (fieldName , v , currentVal ); err != nil {
914- errors = appendErrors ( errors , err )
923+ errs = append ( errs , err )
915924 continue
916925 }
917926
@@ -921,12 +930,7 @@ func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val refle
921930 // Set the built up map to the value
922931 val .Set (valMap )
923932
924- // If we had errors, return those
925- if len (errors ) > 0 {
926- return & joinedError {errors }
927- }
928-
929- return nil
933+ return errors .Join (errs ... )
930934}
931935
932936func (d * Decoder ) decodeMapFromStruct (name string , dataVal reflect.Value , val reflect.Value , valMap reflect.Value ) error {
@@ -1164,7 +1168,7 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
11641168 }
11651169
11661170 // Accumulate any errors
1167- errors := make ([] string , 0 )
1171+ var errs [] error
11681172
11691173 for i := 0 ; i < dataVal .Len (); i ++ {
11701174 currentData := dataVal .Index (i ).Interface ()
@@ -1175,19 +1179,14 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
11751179
11761180 fieldName := name + "[" + strconv .Itoa (i ) + "]"
11771181 if err := d .decode (fieldName , currentData , currentField ); err != nil {
1178- errors = appendErrors ( errors , err )
1182+ errs = append ( errs , err )
11791183 }
11801184 }
11811185
11821186 // Finally, set the value to the slice we built up
11831187 val .Set (valSlice )
11841188
1185- // If there were errors, we return those
1186- if len (errors ) > 0 {
1187- return & joinedError {errors }
1188- }
1189-
1190- return nil
1189+ return errors .Join (errs ... )
11911190}
11921191
11931192func (d * Decoder ) decodeArray (name string , data interface {}, val reflect.Value ) error {
@@ -1233,27 +1232,22 @@ func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value)
12331232 }
12341233
12351234 // Accumulate any errors
1236- errors := make ([] string , 0 )
1235+ var errs [] error
12371236
12381237 for i := 0 ; i < dataVal .Len (); i ++ {
12391238 currentData := dataVal .Index (i ).Interface ()
12401239 currentField := valArray .Index (i )
12411240
12421241 fieldName := name + "[" + strconv .Itoa (i ) + "]"
12431242 if err := d .decode (fieldName , currentData , currentField ); err != nil {
1244- errors = appendErrors ( errors , err )
1243+ errs = append ( errs , err )
12451244 }
12461245 }
12471246
12481247 // Finally, set the value to the array we built up
12491248 val .Set (valArray )
12501249
1251- // If there were errors, we return those
1252- if len (errors ) > 0 {
1253- return & joinedError {errors }
1254- }
1255-
1256- return nil
1250+ return errors .Join (errs ... )
12571251}
12581252
12591253func (d * Decoder ) decodeStruct (name string , data interface {}, val reflect.Value ) error {
@@ -1315,7 +1309,8 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
13151309 }
13161310
13171311 targetValKeysUnused := make (map [interface {}]struct {})
1318- errors := make ([]string , 0 )
1312+
1313+ var errs []error
13191314
13201315 // This slice will keep track of all the structs we'll be decoding.
13211316 // There can be more than one struct if there are embedded structs
@@ -1369,8 +1364,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
13691364
13701365 if squash {
13711366 if fieldVal .Kind () != reflect .Struct {
1372- errors = appendErrors (errors ,
1373- 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 ()))
13741368 } else {
13751369 structs = append (structs , fieldVal )
13761370 }
@@ -1449,7 +1443,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
14491443 }
14501444
14511445 if err := d .decode (fieldName , rawMapVal .Interface (), fieldValue ); err != nil {
1452- errors = appendErrors ( errors , err )
1446+ errs = append ( errs , err )
14531447 }
14541448 }
14551449
@@ -1464,7 +1458,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
14641458
14651459 // Decode it as-if we were just decoding this map onto our map.
14661460 if err := d .decodeMap (name , remain , remainField .val ); err != nil {
1467- errors = appendErrors ( errors , err )
1461+ errs = append ( errs , err )
14681462 }
14691463
14701464 // Set the map to nil so we have none so that the next check will
@@ -1480,7 +1474,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
14801474 sort .Strings (keys )
14811475
14821476 err := fmt .Errorf ("'%s' has invalid keys: %s" , name , strings .Join (keys , ", " ))
1483- errors = appendErrors ( errors , err )
1477+ errs = append ( errs , err )
14841478 }
14851479
14861480 if d .config .ErrorUnset && len (targetValKeysUnused ) > 0 {
@@ -1491,11 +1485,11 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
14911485 sort .Strings (keys )
14921486
14931487 err := fmt .Errorf ("'%s' has unset fields: %s" , name , strings .Join (keys , ", " ))
1494- errors = appendErrors ( errors , err )
1488+ errs = append ( errs , err )
14951489 }
14961490
1497- if len ( errors ) > 0 {
1498- return & joinedError { errors }
1491+ if err := errors . Join ( errs ... ); err != nil {
1492+ return err
14991493 }
15001494
15011495 // Add the unused keys to the list of unused keys if we're tracking metadata
0 commit comments