review: tests on errors

This commit is contained in:
Fernandez Ludovic 2026-03-10 22:41:08 +01:00
commit ac4eee27e5
5 changed files with 67 additions and 30 deletions

View file

@ -19,21 +19,9 @@ import (
querystring "github.com/google/go-querystring/query"
)
// Response codes:
// - 1000: Command completed successfully
// - 1300: Command completed successfully; no messages
// - 2001: Command syntax error
// - 2002: Command use error
// - 2003: Required parameter missing
// - 2004: Parameter value range error
// - 2104: Billing failure
// - 2200: Authentication error
// - 2201: Authorization error
// - 2303: Object does not exist
// - 2304: Object status prohibits operation
// - 2309: Object duplicate found
// - 2400: Command failed
// - 2500: Command failed; server closing connection
type responseChecker interface {
Check() error
}
// Client the Excedo API client.
type Client struct {
@ -84,10 +72,6 @@ func (c *Client) AddRecord(ctx context.Context, record Record) (int64, error) {
return 0, err
}
if result.Code != 1000 && result.Code != 1300 {
return 0, fmt.Errorf("%d: %s", result.Code, result.Description)
}
return result.RecordID, nil
}
@ -111,10 +95,6 @@ func (c *Client) DeleteRecord(ctx context.Context, zone, recordID string) error
return err
}
if result.Code != 1000 && result.Code != 1300 {
return fmt.Errorf("%d: %s", result.Code, result.Description)
}
return nil
}
@ -123,6 +103,7 @@ func (c *Client) GetRecords(ctx context.Context, zone string) (map[string]Zone,
query := endpoint.Query()
query.Set("domainname", zone)
endpoint.RawQuery = query.Encode()
req, err := newFormRequest(ctx, http.MethodGet, endpoint, nil)
@ -137,14 +118,10 @@ func (c *Client) GetRecords(ctx context.Context, zone string) (map[string]Zone,
return nil, err
}
if result.Code != 1000 && result.Code != 1300 {
return nil, fmt.Errorf("%d: %s", result.Code, result.Description)
}
return result.DNS, nil
}
func (c *Client) do(req *http.Request, result any) error {
func (c *Client) do(req *http.Request, result responseChecker) error {
useragent.SetHeader(req.Header)
resp, err := c.HTTPClient.Do(req)
@ -174,7 +151,7 @@ func (c *Client) do(req *http.Request, result any) error {
return errutils.NewUnmarshalError(req, resp.StatusCode, raw, err)
}
return nil
return result.Check()
}
func newMultipartRequest(ctx context.Context, method string, endpoint *url.URL, data map[string]string) (*http.Request, error) {

View file

@ -59,6 +59,30 @@ func TestClient_AddRecord(t *testing.T) {
assert.EqualValues(t, 19695822, recordID)
}
func TestClient_AddRecord_error(t *testing.T) {
client := mockBuilder().
Route("POST /dns/addrecord/",
servermock.ResponseFromFixture("error.json"),
).
Build(t)
client.token = &ExpirableToken{
Token: "session-token",
Expires: time.Now().Add(6 * time.Hour),
}
record := Record{
DomainName: "example.com",
Name: "_acme-challenge",
Type: "TXT",
Content: "ADw2sEd82DUgXcQ9hNBZThJs7zVJkR5v9JeSbAb9mZY",
TTL: "60",
}
_, err := client.AddRecord(t.Context(), record)
require.EqualError(t, err, "2003: Required parameter missing")
}
func TestClient_DeleteRecord(t *testing.T) {
client := mockBuilder().
Route("POST /dns/deleterecord/",

View file

@ -61,7 +61,7 @@ func (c *Client) authenticate(ctx context.Context) (string, error) {
return c.token.Token, nil
}
func (c *Client) doAuthenticated(ctx context.Context, req *http.Request, result any) error {
func (c *Client) doAuthenticated(ctx context.Context, req *http.Request, result responseChecker) error {
token, err := c.authenticate(ctx)
if err != nil {
return err

View file

@ -22,3 +22,14 @@ func TestClient_Login(t *testing.T) {
assert.Equal(t, "session-token", token)
}
func TestClient_Login_error(t *testing.T) {
client := mockBuilder().
Route("GET /authenticate/login/",
servermock.ResponseFromFixture("error.json"),
).
Build(t)
_, err := client.Login(t.Context())
require.EqualError(t, err, "2003: Required parameter missing")
}

View file

@ -1,10 +1,35 @@
package internal
import "fmt"
type BaseResponse struct {
Code int `json:"code"`
Description string `json:"desc"`
}
func (r BaseResponse) Check() error {
// Response codes:
// - 1000: Command completed successfully
// - 1300: Command completed successfully; no messages
// - 2001: Command syntax error
// - 2002: Command use error
// - 2003: Required parameter missing
// - 2004: Parameter value range error
// - 2104: Billing failure
// - 2200: Authentication error
// - 2201: Authorization error
// - 2303: Object does not exist
// - 2304: Object status prohibits operation
// - 2309: Object duplicate found
// - 2400: Command failed
// - 2500: Command failed; server closing connection
if r.Code != 1000 && r.Code != 1300 {
return fmt.Errorf("%d: %s", r.Code, r.Description)
}
return nil
}
type GetRecordsResponse struct {
BaseResponse