@@ -10,6 +10,7 @@ import (
1010 "sync"
1111
1212 "github.com/moov-io/iso8583/encoding"
13+ iso8583errors "github.com/moov-io/iso8583/errors"
1314 "github.com/moov-io/iso8583/prefix"
1415 "github.com/moov-io/iso8583/sort"
1516 "github.com/moov-io/iso8583/utils"
@@ -314,7 +315,7 @@ func (f *Composite) Unpack(data []byte) (int, error) {
314315 // data is stripped of the prefix before it is provided to unpack().
315316 // Therefore, it is unaware of when to stop parsing unless we bound the
316317 // length of the slice by the data length.
317- read , err := f .unpack (data [offset :offset + dataLen ], isVariableLength )
318+ read , err := f .wrapErrorUnpack (data [offset :offset + dataLen ], isVariableLength )
318319 if err != nil {
319320 return 0 , err
320321 }
@@ -333,7 +334,7 @@ func (f *Composite) SetBytes(data []byte) error {
333334 f .mu .Lock ()
334335 defer f .mu .Unlock ()
335336
336- _ , err := f .unpack (data , false )
337+ _ , err := f .wrapErrorUnpack (data , false )
337338 return err
338339}
339340
@@ -517,7 +518,22 @@ func (f *Composite) packByTag() ([]byte, error) {
517518 return packed , nil
518519}
519520
520- func (f * Composite ) unpack (data []byte , isVariableLength bool ) (int , error ) {
521+ // wrapErrorUnpack calls the core unpacking logic and wraps any
522+ // errors in a *UnpackError. It assumes that the mutex is already
523+ // locked by the caller.
524+ func (f * Composite ) wrapErrorUnpack (src []byte , isVariableLength bool ) (int , error ) {
525+ offset , tagID , err := f .unpack (src , isVariableLength )
526+ if err != nil {
527+ return offset , & iso8583errors.UnpackError {
528+ Err : err ,
529+ FieldID : tagID ,
530+ RawMessage : src ,
531+ }
532+ }
533+ return offset , nil
534+ }
535+
536+ func (f * Composite ) unpack (data []byte , isVariableLength bool ) (int , string , error ) {
521537 if f .bitmap () != nil {
522538 return f .unpackSubfieldsByBitmap (data )
523539 }
@@ -527,7 +543,7 @@ func (f *Composite) unpack(data []byte, isVariableLength bool) (int, error) {
527543 return f .unpackSubfields (data , isVariableLength )
528544}
529545
530- func (f * Composite ) unpackSubfields (data []byte , isVariableLength bool ) (int , error ) {
546+ func (f * Composite ) unpackSubfields (data []byte , isVariableLength bool ) (int , string , error ) {
531547 offset := 0
532548 for _ , tag := range f .orderedSpecFieldTags {
533549 field , ok := f .subfields [tag ]
@@ -537,7 +553,7 @@ func (f *Composite) unpackSubfields(data []byte, isVariableLength bool) (int, er
537553
538554 read , err := field .Unpack (data [offset :])
539555 if err != nil {
540- return 0 , fmt .Errorf ("failed to unpack subfield %v: %w" , tag , err )
556+ return 0 , tag , fmt .Errorf ("failed to unpack subfield %v: %w" , tag , err )
541557 }
542558
543559 f .setSubfields [tag ] = struct {}{}
@@ -549,10 +565,10 @@ func (f *Composite) unpackSubfields(data []byte, isVariableLength bool) (int, er
549565 }
550566 }
551567
552- return offset , nil
568+ return offset , "" , nil
553569}
554570
555- func (f * Composite ) unpackSubfieldsByBitmap (data []byte ) (int , error ) {
571+ func (f * Composite ) unpackSubfieldsByBitmap (data []byte ) (int , string , error ) {
556572 var off int
557573
558574 // Reset fields that were set.
@@ -562,7 +578,7 @@ func (f *Composite) unpackSubfieldsByBitmap(data []byte) (int, error) {
562578
563579 read , err := f .bitmap ().Unpack (data [off :])
564580 if err != nil {
565- return 0 , fmt .Errorf ("failed to unpack bitmap: %w" , err )
581+ return 0 , "" , fmt .Errorf ("failed to unpack bitmap: %w" , err )
566582 }
567583
568584 off += read
@@ -573,12 +589,12 @@ func (f *Composite) unpackSubfieldsByBitmap(data []byte) (int, error) {
573589
574590 fl , ok := f .subfields [iStr ]
575591 if ! ok {
576- return 0 , fmt .Errorf ("failed to unpack subfield %s: no specification found" , iStr )
592+ return 0 , iStr , fmt .Errorf ("failed to unpack subfield %s: no specification found" , iStr )
577593 }
578594
579595 read , err = fl .Unpack (data [off :])
580596 if err != nil {
581- return 0 , fmt .Errorf ("failed to unpack subfield %s (%s): %w" , iStr , fl .Spec ().Description , err )
597+ return 0 , iStr , fmt .Errorf ("failed to unpack subfield %s (%s): %w" , iStr , fl .Spec ().Description , err )
582598 }
583599
584600 f .setSubfields [iStr ] = struct {}{}
@@ -587,7 +603,7 @@ func (f *Composite) unpackSubfieldsByBitmap(data []byte) (int, error) {
587603 }
588604 }
589605
590- return off , nil
606+ return off , "" , nil
591607}
592608
593609const (
@@ -598,12 +614,12 @@ const (
598614 maxLenOfUnknownTag = math .MaxInt
599615)
600616
601- func (f * Composite ) unpackSubfieldsByTag (data []byte ) (int , error ) {
617+ func (f * Composite ) unpackSubfieldsByTag (data []byte ) (int , string , error ) {
602618 offset := 0
603619 for offset < len (data ) {
604620 tagBytes , read , err := f .spec .Tag .Enc .Decode (data [offset :], f .spec .Tag .Length )
605621 if err != nil {
606- return 0 , fmt .Errorf ("failed to unpack subfield Tag: %w" , err )
622+ return 0 , "" , fmt .Errorf ("failed to unpack subfield Tag: %w" , err )
607623 }
608624 offset += read
609625
@@ -625,15 +641,15 @@ func (f *Composite) unpackSubfieldsByTag(data []byte) (int, error) {
625641 maxLen = maxLenOfUnknownTag
626642 }
627643
628- fieldLength , readed , err := pref .DecodeLength (maxLen , data [offset :])
644+ fieldLength , read , err := pref .DecodeLength (maxLen , data [offset :])
629645 if err != nil {
630- return 0 , err
646+ return 0 , "" , err
631647 }
632- offset += fieldLength + readed
648+ offset += fieldLength + read
633649 continue
634650 }
635651
636- return 0 , fmt .Errorf ("failed to unpack subfield %v: field not defined in Spec" , tag )
652+ return 0 , tag , fmt .Errorf ("failed to unpack subfield %v: field not defined in Spec" , tag )
637653 }
638654
639655 field , ok := f .subfields [tag ]
@@ -643,14 +659,14 @@ func (f *Composite) unpackSubfieldsByTag(data []byte) (int, error) {
643659
644660 read , err = field .Unpack (data [offset :])
645661 if err != nil {
646- return 0 , fmt .Errorf ("failed to unpack subfield %v: %w" , tag , err )
662+ return 0 , tag , fmt .Errorf ("failed to unpack subfield %v: %w" , tag , err )
647663 }
648664
649665 f .setSubfields [tag ] = struct {}{}
650666
651667 offset += read
652668 }
653- return offset , nil
669+ return offset , "" , nil
654670}
655671
656672func (f * Composite ) skipUnknownTLVTags () bool {
0 commit comments