Skip to content

Commit

Permalink
Add Data field to api errors (#6)
Browse files Browse the repository at this point in the history
Closes #5

This commit adds the `Data` field to the `APIError` type and provides a helper function `ErrorData` to obtain
the slice of errors from the response. This will allow us to expose errors in ACL tests.

Signed-off-by: David Bond <[email protected]>
  • Loading branch information
davidsbond authored Mar 2, 2022
1 parent 632055c commit 20449ae
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
20 changes: 19 additions & 1 deletion tailscale/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,17 @@ type (

// The APIError type describes an error as returned by the Tailscale API.
APIError struct {
Message string `json:"message"`
Message string `json:"message"`
Data []APIErrorData `json:"data"`
status int
}

// The APIErrorData type describes elements of the data field within errors returned by the Tailscale API.
APIErrorData struct {
User string `json:"user"`
Errors []string `json:"errors"`
}

// The ClientOption type is a function that is used to modify a Client.
ClientOption func(c *Client) error
)
Expand Down Expand Up @@ -485,3 +492,14 @@ func IsNotFound(err error) bool {

return false
}

// ErrorData returns the contents of the APIError.Data field from the provided error if it is of type APIError. Returns
// a nil slice if the given error is not of type APIError.
func ErrorData(err error) []APIErrorData {
var apiErr APIError
if errors.As(err, &apiErr) {
return apiErr.Data
}

return nil
}
25 changes: 25 additions & 0 deletions tailscale/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
_ "embed"
"encoding/json"
"io"
"net/http"
"testing"
"time"
Expand Down Expand Up @@ -537,3 +538,27 @@ func TestClient_SetDeviceTags(t *testing.T) {
assert.NoError(t, json.Unmarshal(server.Body.Bytes(), &body))
assert.EqualValues(t, tags, body["tags"])
}

func TestErrorData(t *testing.T) {
t.Parallel()

t.Run("It should return the data element from a valid error", func(t *testing.T) {
expected := tailscale.APIError{
Data: []tailscale.APIErrorData{
{
User: "[email protected]",
Errors: []string{
"address \"[email protected]:400\": want: Accept, got: Drop",
},
},
},
}

actual := tailscale.ErrorData(expected)
assert.EqualValues(t, expected.Data, actual)
})

t.Run("It should return an empty slice for any other error", func(t *testing.T) {
assert.Empty(t, tailscale.ErrorData(io.EOF))
})
}

0 comments on commit 20449ae

Please sign in to comment.