fix: better errors.

This commit is contained in:
Andrey Parhomenko 2024-03-04 06:31:33 +05:00
parent ebd4866455
commit 28f6a7e2ec
3 changed files with 63 additions and 43 deletions

View file

@ -2,6 +2,8 @@ package amo
import (
"fmt"
"time"
"errors"
"vultras.su/core/amo/api"
"vultras.su/core/amo/companies"
"vultras.su/core/amo/contacts"
@ -92,7 +94,8 @@ func (client *Client) GetEvents(req events.EventsRequest) ([]events.Event, error
resp := events.EventsResponse{}
err := client.Api.Get(res, &resp, abs)
if err != nil {
if err == api.NoContentErr {
// Return empty if no content avialable.
if errors.Is(err, api.NoContentErr) {
return ret, nil
}
return nil, err
@ -101,6 +104,7 @@ func (client *Client) GetEvents(req events.EventsRequest) ([]events.Event, error
if resp.Links.Next.Href == "" {
break
}
time.Sleep(time.Millisecond*300)
abs = true
res = resp.Links.Next.Href
}

View file

@ -1,16 +1,17 @@
package api
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"errors"
"bytes"
"time"
"fmt"
"log"
"io"
"os"
"time"
)
const (
@ -35,10 +36,11 @@ type ClientOptions struct {
}
type Client struct {
*log.Logger
options *ClientOptions
BaseUrl *url.URL
secretStoreFilePath string
Debug bool `json`
Debug bool
}
type requestOptions struct {
@ -60,42 +62,43 @@ type TokenPair struct {
}
func NewApi(secretPath string) (*Client, error) {
ret := &Client{
client := &Client{
Logger: log.New(os.Stdout, "AmoCRM client: ", log.Ldate | log.Ltime),
secretStoreFilePath: secretPath,
}
options, err := ret.readSecret()
options, err := client.readSecret()
if err != nil {
return nil, err
return nil, NewApiError(err)
}
if client.Debug {
client.Printf("ClientOptions: %v\n", options)
}
fmt.Println("opts:", options)
if options.Url == "" || options.RedirectUrl == "" {
return nil, errors.New("AmoCrm: Invalid options: Url")
return nil, NewApiError(InvalidUrlOptionsErr)
}
resolvedUrl, err := url.Parse(options.Url)
if err != nil {
return nil, err
return nil, NewApiError(err)
}
ret.BaseUrl = resolvedUrl
if err != nil {
return nil, err
}
ret.options = options
client.BaseUrl = resolvedUrl
client.options = options
var (
//pair *TokenPair
exchangeErr error
exchanged bool
)
if ret.options.AccessToken == "" && ret.options.RefreshToken == "" {
if ret.options.ClientSecret == "" ||
ret.options.ClientId == "" ||
ret.options.AuthCode == "" {
return nil, errors.New("AmoCrm: invalid options: ExchangeAuth")
if client.options.AccessToken == "" && client.options.RefreshToken == "" {
if client.options.ClientSecret == "" ||
client.options.ClientId == "" ||
client.options.AuthCode == "" {
return nil, NewApiError(InvalidExchangeAuthOptionsErr)
}
_, exchangeErr = ret.ExchangeAuth()
_, exchangeErr = client.ExchangeAuth()
exchanged = true
}
@ -103,16 +106,13 @@ func NewApi(secretPath string) (*Client, error) {
// Refreshing token before the work.
// Should think of how often should refresh
// the token. (see the ExpiresIn)
_, err = ret.RefreshToken()
_, err = client.RefreshToken()
if err != nil {
return nil, err
return nil, NewApiError(err)
}
}
return &Client{
options: options,
BaseUrl: resolvedUrl,
}, nil
return client, nil
}
func (api *Client) readSecret() (*ClientOptions, error) {
@ -190,37 +190,40 @@ func (api *Client) rdoRequest(resourceUrl string, requestParams requestOptions,
response, err := http.DefaultClient.Do(request)
if api.Debug {
fmt.Printf("\nAmo request: %+v\nAmo repsonse: %+v\n", request, response)
api.Printf("Request: %+v\n\nAmo response: %+v\n\n", request, response)
}
if response == nil {
return NoInternetErr
return RequestError(NoInternetErr)
}
if err != nil {
return errors.New(fmt.Sprintf(
"Request error: %s %d %s %s",
err.Error(),
return RequestError(fmt.Errorf(
"%w: %d %s %s",
err,
response.StatusCode,
requestParams.HttpMethod,
resourceUrl,
))
}
defer response.Body.Close()
if response.StatusCode == 204 {
return NoContentErr
return RequestError(NoContentErr)
}
if response.StatusCode >= 400 {
var specErr error
if response.StatusCode == 401 {
return NoAuthErr
specErr = NoAuthErr
}
bodyBytes, _ := ioutil.ReadAll(response.Body)
return errors.New(fmt.Sprintf(
"%s %d %s %s",
string(bodyBytes),
response.StatusCode,
responseErrorInfo, _ := ioutil.ReadAll(response.Body)
return RequestError(fmt.Errorf(
"%w: %s %s %q %d",
specErr,
requestParams.HttpMethod,
resourceUrl,
string(responseErrorInfo),
response.StatusCode,
))
}
@ -239,7 +242,7 @@ func (api *Client) doRequest(
) error {
var err error
err = api.rdoRequest(resourceUrl, requestParams, result)
if err == NoAuthErr && api.options.RefreshToken != "" {
if errors.Is(err, NoAuthErr) && api.options.RefreshToken != "" {
_, err = api.RefreshToken()
if err != nil {
return nil

View file

@ -2,10 +2,23 @@ package api
import (
"errors"
"fmt"
)
var (
NoContentErr = errors.New("no content")
NoAuthErr = errors.New("not authorized")
NoInternetErr = errors.New("no Internet provided")
InvalidUrlOptionsErr = errors.New("invalid URL options")
InvalidExchangeAuthOptionsErr = errors.New("invalid ExchangeAuth options")
UrlParsingErr = errors.New("URL parsing")
)
func NewApiError(err error) error {
return fmt.Errorf("NewApi: %w", err)
}
func RequestError(err error) error {
return fmt.Errorf("RequestError: %w", err)
}