Skip to content

Commit

Permalink
Define separate error types for activation service errors (#986)
Browse files Browse the repository at this point in the history
* Define separate error types for activation service errors

* Add HTTP Status code to ActivationServiceError

* Tests: Comply with Pascal case
  • Loading branch information
sameh-farouk authored Jul 10, 2024
1 parent 54805ca commit 5a9ad37
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 6 deletions.
25 changes: 19 additions & 6 deletions clients/tfchain-client-go/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,19 @@ type AccountInfo struct {
Data Balance `json:"data"`
}

// TODO: Add service response status code if avialble
type ActivationServiceError struct {
StatusCode int // 0 or a valid HTTP status code. 0 indicates that a response was not recived due to an error such host unreachable.
Err error
}

func (e ActivationServiceError) Error() string {
if e.StatusCode != 0 {
return fmt.Sprintf("Activation service error (status code %d): %s", e.StatusCode, e.Err.Error())
}
return fmt.Sprintf("Activation service error: %s", e.Err.Error())
}

// PublicKey gets public key from account id
func (a AccountID) PublicKey() []byte {
return a[:]
Expand Down Expand Up @@ -135,7 +148,7 @@ func (s *Substrate) activateAccount(identity Identity, activationURL string) err

response, err := http.Post(activationURL, "application/json", &buf)
if err != nil {
return errors.Wrap(err, "failed to call activation service")
return ActivationServiceError{Err: errors.Wrap(err, "failed to call activation service")}
}

defer response.Body.Close()
Expand All @@ -145,22 +158,22 @@ func (s *Substrate) activateAccount(identity Identity, activationURL string) err
return nil
}

return fmt.Errorf("failed to activate account: %s", response.Status)
return ActivationServiceError{StatusCode: response.StatusCode, Err: fmt.Errorf("activation service returned status code %d", response.StatusCode)}
}

// EnsureAccount makes sure account is available on blockchain
// if not, it uses activation service to create one.
// EnsureAccount is safe to call on already activated accounts and it's mostly
// a NO-OP operation unless the account funds are very low, it will then make
// sure to reactivate the account (fund it) if the free tokes are <= ReactivateThreefold uTFT
func (s *Substrate) EnsureAccount(identity Identity, activationURL, termsAndConditionsLink, terminsAndConditionsHash string) (info AccountInfo, err error) {
// sure to reactivate the account (fund it) if the free tokens are <= ReactivateThreefold uTFT
func (s *Substrate) EnsureAccount(identity Identity, activationURL, termsAndConditionsLink, termsAndConditionsHash string) (info AccountInfo, err error) {
log.Debug().Str("account", identity.Address()).Msg("ensuring account")
cl, meta, err := s.GetClient()
if err != nil {
return info, err
}
info, err = s.getAccount(cl, meta, identity)
// if account does not exist OR account has tokes less that reactivateAt
// if account does not exist OR account has tokens less than reactivateAt
// then we activate the account.
if errors.Is(err, ErrAccountNotFound) || info.Data.Free.Cmp(reactivateAt) <= 0 {
// account activation
Expand Down Expand Up @@ -203,7 +216,7 @@ func (s *Substrate) EnsureAccount(identity Identity, activationURL, termsAndCond
return info, nil
}

return info, s.AcceptTermsAndConditions(identity, termsAndConditionsLink, terminsAndConditionsHash)
return info, s.AcceptTermsAndConditions(identity, termsAndConditionsLink, termsAndConditionsHash)
}

// Identity is a user identity
Expand Down
15 changes: 15 additions & 0 deletions clients/tfchain-client-go/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,18 @@ func TestGetBalance(t *testing.T) {
_, err = cl.GetBalance(account)
require.NoError(err)
}

func TestEnsureAccountWithDownActivationService(t *testing.T) {
cl := startLocalConnection(t)
defer cl.Close()

require := require.New(t)
id, err := NewIdentityFromEd25519Phrase("paper endless radio rude wage hood cabin praise girl income chief craft")
require.NoError(err)
_, err = cl.EnsureAccount(id, "https://test.wrong-activation-service-url.tf", "test", "test")
require.Error(err)
require.IsType(ActivationServiceError{}, err)
_, err = cl.EnsureAccount(id, "https://httpstat.us/503", "test", "test")
require.Error(err)
require.IsType(ActivationServiceError{}, err)
}

0 comments on commit 5a9ad37

Please sign in to comment.