From 79113948441c3c84c21c0ed1fb1aa4212cbb77a1 Mon Sep 17 00:00:00 2001 From: NibiruHeisenberg <101130700+NibiruHeisenberg@users.noreply.github.com> Date: Wed, 30 Nov 2022 20:26:35 -0500 Subject: [PATCH] chore: update error message (#6) --- iter.go | 2 +- keys.go | 38 +++++++++++++++++++++++++++++++------- keyset.go | 2 +- values.go | 6 ++++-- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/iter.go b/iter.go index aed1445..d9fe9e4 100644 --- a/iter.go +++ b/iter.go @@ -139,7 +139,7 @@ func iteratorFromRange[K, V any](s sdk.KVStore, r Ranger[K], kc KeyEncoder[K], v case OrderDescending: iter = s.ReverseIterator(startBytes, endBytes) default: - panic("unrecognized Order") + panic(fmt.Errorf("unrecognized Order: %v", order)) } return Iterator[K, V]{ diff --git a/keys.go b/keys.go index 9b9cb5c..68ba463 100644 --- a/keys.go +++ b/keys.go @@ -37,14 +37,16 @@ func (stringKey) Encode(s string) []byte { func (stringKey) Decode(b []byte) (int, string) { l := len(b) if l < 2 { - panic("invalid StringKey bytes") + panic(fmt.Errorf( + "invalid StringKey bytes. StringKey must be at least length 2. %s", + HumanizeBytes(b))) } for i, c := range b { if c == 0 { return i + 1, string(b[:i]) } } - panic(fmt.Errorf("string is not null terminated: %s", b)) + panic(fmt.Errorf("string is not null terminated: %s %s", b, HumanizeBytes(b))) } type uint64Key struct{} @@ -60,7 +62,7 @@ func (timeKey) Encode(t time.Time) []byte { return sdk.FormatTimeBytes(t) } func (timeKey) Decode(b []byte) (int, time.Time) { t, err := sdk.ParseTimeBytes(b) if err != nil { - panic(err) + panic(fmt.Errorf("%w %s", err, HumanizeBytes(b))) } return len(b), t } @@ -85,7 +87,7 @@ func (v valAddressKeyEncoder) Decode(b []byte) (int, sdk.ValAddress) { r, s := StringKeyEncoder.Decode(b) valAddr, err := sdk.ValAddressFromBech32(s) if err != nil { - panic(err) + panic(fmt.Errorf("%w %s", err, HumanizeBytes(b))) } return r, valAddr } @@ -113,7 +115,7 @@ func (consAddressKeyEncoder) Decode(b []byte) (int, sdk.ConsAddress) { r, s := StringKeyEncoder.Decode(b) consAddr, err := sdk.ConsAddressFromBech32(s) if err != nil { - panic(err) + panic(fmt.Errorf("%w %s", err, HumanizeBytes(b))) } return r, consAddr } @@ -126,15 +128,37 @@ func (sdkDecKeyEncoder) Stringify(key sdk.Dec) string { return key.String() } func (sdkDecKeyEncoder) Encode(key sdk.Dec) []byte { bz, err := key.Marshal() if err != nil { - panic(fmt.Errorf("invalid DecKey: %w", err)) + panic(fmt.Errorf("invalid DecKey: %w %s", err, HumanizeBytes(bz))) } return bz } func (sdkDecKeyEncoder) Decode(b []byte) (int, sdk.Dec) { var dec sdk.Dec if err := dec.Unmarshal(b); err != nil { - panic(fmt.Errorf("invalid DecKey bytes: %w", err)) + panic(fmt.Errorf("invalid DecKey bytes: %w %s", err, HumanizeBytes(b))) } return len(b), dec } + +// HumanizeBytes is a shorthand function for converting a slice of bytes ([]byte) +// into to hexadecimal string with a short descriptor. This function is meant to +// make error messages more readable since the bytes will be reproducable. +// +// For example, +// ```go +// import "encoding/hex" +// import "fmt" +// +// // When logging the hex string... +// bz := []byte("ABC€日本語") +// bytesAsHex := fmt.Sprintf("%x", bz) // 414243e282ace697a5e69cace8aa9e +// +// // Later when debugging using the logs, the original bytes can be found +// // easily using the 'bytesAsHex' +// bz, _ := hex.DecodeString("414243e282ace697a5e69cace8aa9e") +// fmt.Println(string(bz)) // ABC€日本語 +// ```` +func HumanizeBytes(bz []byte) string { + return fmt.Sprintf("\nbytesAsHex: %x", bz) +} diff --git a/keyset.go b/keyset.go index 72a9463..ca59f33 100644 --- a/keyset.go +++ b/keyset.go @@ -68,7 +68,7 @@ func (s setObject) Encode(_ setObject) []byte { return []byte{} } func (s setObject) Decode(b []byte) setObject { if !bytes.Equal(b, []byte{}) { - panic(fmt.Sprintf("invalid bytes: %s", b)) + panic(fmt.Sprintf("invalid bytes: %s %s", b, HumanizeBytes(b))) } return setObject{} } diff --git a/values.go b/values.go index 0fc2a7e..808a6b0 100644 --- a/values.go +++ b/values.go @@ -1,6 +1,8 @@ package collections import ( + "fmt" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/gogo/protobuf/proto" @@ -45,7 +47,7 @@ type decValue struct{} func (d decValue) Encode(value sdk.Dec) []byte { b, err := value.Marshal() if err != nil { - panic(err) + panic(fmt.Errorf("%w %s", err, HumanizeBytes(b))) } return b } @@ -54,7 +56,7 @@ func (d decValue) Decode(b []byte) sdk.Dec { dec := new(sdk.Dec) err := dec.Unmarshal(b) if err != nil { - panic(err) + panic(fmt.Errorf("%w %s", err, HumanizeBytes(b))) } return *dec }