Skip to content

Commit

Permalink
Easier Rejection Errors (trisacrypto#161)
Browse files Browse the repository at this point in the history
  • Loading branch information
bbengfort authored May 25, 2024
1 parent 4d23c2b commit 9ba45a2
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 1 deletion.
41 changes: 40 additions & 1 deletion pkg/trisa/envelope/envelope.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,24 @@ func Wrap(msg *api.SecureEnvelope, opts ...Option) (env *Envelope, err error) {
return env, nil
}

// Wrap error initializes an Envelope from a TRISA error to prepare and validate a
// rejection response without going directly to the SecureEnvelope.
func WrapError(reject *api.Error, opts ...Option) (env *Envelope, err error) {
if env, err = New(nil, opts...); err != nil {
return nil, err
}

if env, err = env.Reject(reject); err != nil {
return nil, err
}

if err = env.ValidateMessage(); err != nil {
return nil, err
}

return env, nil
}

// Validate is a one-liner for Wrap(msg).ValidateMessage() and can be used to ensure
// that a secure envelope has been correctly initialized and can be processed.
func Validate(msg *api.SecureEnvelope) (err error) {
Expand Down Expand Up @@ -802,7 +820,7 @@ func (e *Envelope) ValidateMessage() error {
if e.msg.Error == nil || e.msg.Error.IsZero() {
return ErrNoMessageData
}
return nil
return e.ValidateError()
}

// If there is a payload then all payload fields should be set
Expand Down Expand Up @@ -853,3 +871,24 @@ func (e *Envelope) ValidatePayload() error {

return nil
}

// ValidateError returns an error if the error message is missing details
func (e *Envelope) ValidateError() error {
if e.msg.Error == nil {
return ErrNoError
}

if e.msg.Error.Code == api.Unhandled {
return ErrMissingErrorCode
}

if _, ok := api.Error_Code_name[int32(e.msg.Error.Code)]; !ok {
return ErrInvalidErrorCode
}

if e.msg.Error.Message == "" {
return ErrMissingErrorMessage
}

return nil
}
55 changes: 55 additions & 0 deletions pkg/trisa/envelope/envelope_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,61 @@ func TestTimestamp(t *testing.T) {
}
}

func TestWrapError(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
testCases := []struct {
reject *api.Error
opts []envelope.Option
}{
{
&api.Error{Code: api.BeneficiaryNameUnmatched, Message: "unknown beneficiary, please update your KYC records and try again", Retry: true},
nil,
},
{
&api.Error{Code: api.HighRisk, Message: "high risk transaction, do not send or apply transaction to chain", Retry: false},
[]envelope.Option{envelope.WithEnvelopeID(uuid.NewString())},
},
}

for i, tc := range testCases {
env, err := envelope.WrapError(tc.reject, tc.opts...)
require.NoError(t, err, "could not correctly wrap error %d", i)
require.Equal(t, envelope.Error, env.State(), "incorrect state for test case %d", err)
require.Equal(t, tc.reject, env.Error(), "test case %d failed error mismatch", i)
}
})

t.Run("Invalid", func(t *testing.T) {
testCases := []struct {
reject *api.Error
opts []envelope.Option
expected error
}{
{
&api.Error{Code: api.BeneficiaryNameUnmatched, Message: "", Retry: true},
nil,
envelope.ErrMissingErrorMessage,
},
{
&api.Error{Code: api.Unhandled, Message: "high risk transaction, do not send or apply transaction to chain", Retry: false},
[]envelope.Option{envelope.WithEnvelopeID(uuid.NewString())},
envelope.ErrMissingErrorCode,
},
{
&api.Error{Code: api.Error_Code(21332122), Message: "this is not a good error", Retry: true},
nil,
envelope.ErrInvalidErrorCode,
},
}

for i, tc := range testCases {
_, err := envelope.WrapError(tc.reject, tc.opts...)
require.ErrorIs(t, err, tc.expected, "expected validation error on test case %d", i)
}
})

}

const (
expectedEnvelopeId = "2b3b4c95-0a78-4f2a-a9fa-041970f97144"
)
Expand Down
4 changes: 4 additions & 0 deletions pkg/trisa/envelope/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ var (
ErrNoSentAtPayload = errors.New("invalid payload: sent at timestamp is missing")
ErrInvalidSentAtPayload = errors.New("invalid payload: could not parse sent at timestamp in RFC3339 format")
ErrInvalidReceivedatPayload = errors.New("invalid payload: could not parse received at timestamp in RFC3339 format")
ErrNoError = errors.New("invalid rejection: missing expected rejection error")
ErrMissingErrorCode = errors.New("invalid rejection: missing error code")
ErrMissingErrorMessage = errors.New("invalid rejection: missing error message")
ErrInvalidErrorCode = errors.New("invalid rejection: unknown trisa error code")
ErrCannotEncrypt = errors.New("cannot encrypt envelope: no cryptographic handler available")
ErrCannotSeal = errors.New("cannot seal envelope: no public key cryptographic handler available")
ErrCannotUnseal = errors.New("cannot unseal envelope: no private key cryptographic handler available")
Expand Down

0 comments on commit 9ba45a2

Please sign in to comment.