Skip to content

Commit

Permalink
refactor: decoder sentinel errors (#428)
Browse files Browse the repository at this point in the history
  • Loading branch information
muktihari authored Sep 13, 2024
1 parent e03e478 commit 68a45e7
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 36 deletions.
32 changes: 15 additions & 17 deletions decoder/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,19 @@ type errorString string
func (e errorString) Error() string { return string(e) }

const (
// Integrity errors
ErrNotFITFile = errorString("not a FIT file")
ErrDataSizeZero = errorString("data size zero")
// ErrNotFITFile will be returned when the first byte every FIT sequence does not match
// with FIT FileHeader's Size specification (either 12 or 15), byte 8-12 is not ".FIT",
// or byte 4-8 are all zero (FileHeader's DataSize == 0).
ErrNotFITFile = errorString("not a FIT file")

// ErrCRCChecksumMismatch will be returned when the CRC checksum is mismatch
// with the CRC in the file, whether on checking FileHeader or Messages integrity.
ErrCRCChecksumMismatch = errorString("crc checksum mismatch")

// Message-field related errors
ErrMesgDefMissing = errorString("message definition missing")
ErrFieldValueTypeMismatch = errorString("field value type mismatch")
ErrInvalidBaseType = errorString("invalid basetype")
// ErrMesgDefMissing will be returned when message definition for the incoming message data is missing.
ErrMesgDefMissing = errorString("message definition missing") // NOTE: Kept exported since it's used by RawDecoder

errInvalidBaseType = errorString("invalid basetype")
)

// Decoder is FIT file decoder. See New() for details.
Expand Down Expand Up @@ -493,7 +497,7 @@ func (d *Decoder) decodeFileHeader() error {
}

if d.fileHeader.DataSize == 0 {
return ErrDataSizeZero
return fmt.Errorf("invalid data size: %w", ErrNotFITFile)
}

if size == 14 {
Expand Down Expand Up @@ -575,7 +579,7 @@ func (d *Decoder) decodeMessageDefinition(header byte) error {
baseType = basetype.BaseType(b[2])
if !baseType.Valid() {
return fmt.Errorf("message definition number: %s(%d): fields[%d].BaseType: %s: %w",
mesgDef.MesgNum, mesgDef.MesgNum, len(mesgDef.FieldDefinitions), baseType, ErrInvalidBaseType)
mesgDef.MesgNum, mesgDef.MesgNum, len(mesgDef.FieldDefinitions), baseType, errInvalidBaseType)
}
mesgDef.FieldDefinitions = append(mesgDef.FieldDefinitions,
proto.FieldDefinition{
Expand Down Expand Up @@ -741,13 +745,7 @@ func (d *Decoder) decodeFields(mesgDef *proto.MessageDefinition, mesg *proto.Mes
val = valueFromBits(bitVal, field.BaseType)
}

if field.Num == proto.FieldNumTimestamp {
if val.Type() != proto.TypeUint32 {
// This can only happen when:
// 1. Profile.xlsx contain typo from official release or user add manufacturer specific message but specifying wrong type.
// 2. User register the message in the factory but using different type.
return fmt.Errorf("timestamp should be uint32, got: %T: %w", val.Any(), ErrFieldValueTypeMismatch)
}
if field.Num == proto.FieldNumTimestamp && val.Type() == proto.TypeUint32 {
timestamp := val.Uint32()
d.timestamp = timestamp
d.lastTimeOffset = byte(timestamp & proto.CompressedTimeMask)
Expand Down Expand Up @@ -882,7 +880,7 @@ func (d *Decoder) decodeDeveloperFields(mesgDef *proto.MessageDefinition, mesg *

if !fieldDesc.FitBaseTypeId.Valid() {
return fmt.Errorf("fieldDescription.FitBaseTypeId: %s: %w",
fieldDesc.FitBaseTypeId, ErrInvalidBaseType)
fieldDesc.FitBaseTypeId, errInvalidBaseType)
}

var isArray bool
Expand Down
22 changes: 3 additions & 19 deletions decoder/decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ func TestCheckIntegrity(t *testing.T) {
return bytes.NewReader(b)
}(),
n: 0,
err: ErrDataSizeZero,
err: ErrNotFITFile,
},
{
name: "read message return error",
Expand Down Expand Up @@ -1392,7 +1392,7 @@ func TestDecodeMessageDefinition(t *testing.T) {
})
}(),
header: proto.MesgDefinitionMask,
err: ErrInvalidBaseType,
err: errInvalidBaseType,
},
}

Expand Down Expand Up @@ -1627,22 +1627,6 @@ func TestDecodeFields(t *testing.T) {
},
},
},
{
name: "decode fields timestamp not uint32",
r: fnReaderOK,
mesgdef: &proto.MessageDefinition{
Header: proto.MesgDefinitionMask,
MesgNum: 68,
FieldDefinitions: []proto.FieldDefinition{
{
Num: proto.FieldNumTimestamp,
Size: 1,
BaseType: basetype.Uint8,
},
},
},
err: ErrFieldValueTypeMismatch,
},
{
name: "decode fields accumulate distance",
r: fnReaderOK,
Expand Down Expand Up @@ -2266,7 +2250,7 @@ func TestDecodeDeveloperFields(t *testing.T) {
},
},
mesg: &proto.Message{},
err: ErrInvalidBaseType,
err: errInvalidBaseType,
},
}

Expand Down

0 comments on commit 68a45e7

Please sign in to comment.