Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create new error abstraction for field validation #239

Merged
merged 29 commits into from
Jan 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
62fbec9
NewName should be optional
Integralist Nov 20, 2020
c8266eb
create generic error type
Integralist Nov 20, 2020
4767b38
update service validation
Integralist Nov 20, 2020
3d1412b
service version 'comment' is required
Integralist Nov 20, 2020
f5da772
clarify in README use of pointers for mandatory fields on list operat…
Integralist Dec 8, 2020
4d6ee69
remove unnecessary TLS prefix
Integralist Dec 8, 2020
fdbcd02
when updating a dict item, the value should be required not optional
Integralist Dec 9, 2020
d21907d
indicate both fields are required
Integralist Dec 18, 2020
5fce681
capture domain update 'optional field' error in a test
Integralist Dec 18, 2020
b5061f2
start moving errors over to new field error type
Integralist Dec 18, 2020
ec17c1f
fix honeycomb to use new error field
Integralist Dec 18, 2020
d9fafa8
fix resources to use new error field validation
Integralist Dec 18, 2020
4354cee
refactor method name on FieldError
Integralist Dec 21, 2020
91865f8
tweak docstring for FieldError#Error
Integralist Dec 21, 2020
ed2e228
revert a possibly unnecessary change
Integralist Dec 21, 2020
8b2351a
update README (v2 and v3 links)
Integralist Jan 4, 2021
5bf8b58
update go.mod to v3
Integralist Jan 4, 2021
d8c505c
revert to sentinel errors
Integralist Jan 5, 2021
962ab15
remove note
Integralist Jan 5, 2021
33c924a
revert errors.Is
Integralist Jan 5, 2021
75af790
fix managed logging code as rebase cleared a new error sentinel
Integralist Jan 19, 2021
2a4023d
update README to reflect merged breaking changes
Integralist Jan 19, 2021
ad53703
fix bad rebase
Integralist Jan 19, 2021
8b02ccc
revert change to DitionaryUpdate ItemValue (we'll move to separate PR)
Integralist Jan 19, 2021
d7870fa
revert change to NewName being optional (we'll move to separate PR)
Integralist Jan 19, 2021
72e149f
Avoid hardcoded strings for validating errors
Integralist Jan 19, 2021
ce9a8a1
revert change to TLS Configuration and Domain (we'll move to separate…
Integralist Jan 19, 2021
7b9ef85
revert change from Service to ServiceID (we'll move to separate PR)
Integralist Jan 19, 2021
dc644df
revert change from ID to ServiceID (we'll move to separate PR)
Integralist Jan 19, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Go Fastly

[![Go Documentation](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)][godocs]
[![Go Documentation](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)][latest]

[godocs]: https://pkg.go.dev/github.com/fastly/go-fastly/fastly?tab=doc
[v2]: https://pkg.go.dev/github.com/fastly/go-fastly/v2
[latest]: https://pkg.go.dev/github.com/fastly/go-fastly/v3/fastly
[v3]: https://pkg.go.dev/github.com/fastly/go-fastly/v3/fastly
[v2]: https://pkg.go.dev/github.com/fastly/go-fastly/v2/fastly
[v1]: https://pkg.go.dev/github.com/fastly/go-fastly

Go Fastly is a Golang API client for interacting with most facets of the
Expand All @@ -17,7 +18,7 @@ so you must be running Go 1.11 or higher.
## Usage

```go
import "github.com/fastly/go-fastly/v2/fastly"
import "github.com/fastly/go-fastly/v3/fastly"
```

## Migrating from v1 to v2
Expand All @@ -31,6 +32,16 @@ The move to more consistent field names in some cases will have resulted in the

The change in type for [basic types](https://tour.golang.org/basics/11) that are optional on input structs related to write/update operations is designed to avoid unexpected behaviours when dealing with their zero value (see [this reference](https://willnorris.com/2014/05/go-rest-apis-and-pointers/) for more details). As part of this change we now provide [helper functions](./fastly/basictypes_helper.go) to assist with generating the new pointer types required.

> Note: some read/list operations require fields to be provided but if omitted a zero value will be used when marshaling the data structure into JSON. This too can cause confusion, which is why some input structs define their mandatory fields as pointers (to ensure that the backend can distinguish between a zero value and an omitted field).

## Migrating from v2 to v3

There were a few breaking changes introduced in [`v3.0.0`][v3]:

1. A new `FieldError` abstraction for validating API struct fields.
2. Changing some mandatory fields to Optional (and vice-versa) to better support more _practical_ API usage.
3. Avoid generic ID field when more explicit naming would be clearer.

## Examples

Fastly's API is designed to work in the following manner:
Expand Down Expand Up @@ -128,7 +139,7 @@ fmt.Printf("%t\n", activeVersion.Locked)
```

More information can be found in the
[Fastly Godoc][godocs].
[Fastly Godoc][latest].

## Developing

Expand Down
3 changes: 1 addition & 2 deletions fastly/acl_entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,6 @@ type BatchACLEntry struct {
}

func (c *Client) BatchModifyACLEntries(i *BatchModifyACLEntriesInput) error {

if i.ServiceID == "" {
return ErrMissingServiceID
}
Expand All @@ -252,7 +251,7 @@ func (c *Client) BatchModifyACLEntries(i *BatchModifyACLEntriesInput) error {
}

if len(i.Entries) > BatchModifyMaximumOperations {
return ErrBatchUpdateMaximumOperationsExceeded
return ErrMaxExceededEntries
}

path := fmt.Sprintf("/service/%s/acl/%s/entries", i.ServiceID, i.ACLID)
Expand Down
6 changes: 4 additions & 2 deletions fastly/acl_entry_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_ACLEntries(t *testing.T) {

Expand Down Expand Up @@ -273,7 +275,7 @@ func TestClient_BatchModifyACLEntries_validation(t *testing.T) {
ACLID: "bar",
Entries: oversizedACLEntries,
})
if err != ErrBatchUpdateMaximumOperationsExceeded {
if err != ErrMaxExceededEntries {
t.Errorf("bad error: %s", err)
}

Expand Down
4 changes: 3 additions & 1 deletion fastly/acl_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_ACLs(t *testing.T) {
t.Parallel()
Expand Down
4 changes: 3 additions & 1 deletion fastly/backend_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_Backends(t *testing.T) {
t.Parallel()
Expand Down
4 changes: 3 additions & 1 deletion fastly/blobstorage_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_BlobStorages(t *testing.T) {
t.Parallel()
Expand Down
4 changes: 3 additions & 1 deletion fastly/cache_setting_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_CacheSettings(t *testing.T) {
t.Parallel()
Expand Down
4 changes: 3 additions & 1 deletion fastly/cloudfiles_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_Cloudfiles(t *testing.T) {
t.Parallel()
Expand Down
4 changes: 3 additions & 1 deletion fastly/condition_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_Conditions(t *testing.T) {
t.Parallel()
Expand Down
4 changes: 3 additions & 1 deletion fastly/custom_tls_certificate_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_CustomTLSCertificate(t *testing.T) {
t.Parallel()
Expand Down
4 changes: 3 additions & 1 deletion fastly/custom_tls_configuration_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_CustomTLSConfiguration(t *testing.T) {
t.Parallel()
Expand Down
4 changes: 3 additions & 1 deletion fastly/datadog_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_Datadog(t *testing.T) {
t.Parallel()
Expand Down
14 changes: 7 additions & 7 deletions fastly/dictionary_item.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (c *Client) ListDictionaryItems(i *ListDictionaryItemsInput) ([]*Dictionary
}

if i.DictionaryID == "" {
return nil, ErrMissingDictionary
return nil, ErrMissingDictionaryID
}

path := fmt.Sprintf("/service/%s/dictionary/%s/items", i.ServiceID, i.DictionaryID)
Expand Down Expand Up @@ -82,7 +82,7 @@ func (c *Client) CreateDictionaryItem(i *CreateDictionaryItemInput) (*Dictionary
}

if i.DictionaryID == "" {
return nil, ErrMissingDictionary
return nil, ErrMissingDictionaryID
}

path := fmt.Sprintf("/service/%s/dictionary/%s/item", i.ServiceID, i.DictionaryID)
Expand Down Expand Up @@ -131,7 +131,7 @@ func (c *Client) GetDictionaryItem(i *GetDictionaryItemInput) (*DictionaryItem,
}

if i.DictionaryID == "" {
return nil, ErrMissingDictionary
return nil, ErrMissingDictionaryID
}

if i.ItemKey == "" {
Expand Down Expand Up @@ -172,7 +172,7 @@ func (c *Client) UpdateDictionaryItem(i *UpdateDictionaryItemInput) (*Dictionary
}

if i.DictionaryID == "" {
return nil, ErrMissingDictionary
return nil, ErrMissingDictionaryID
}

if i.ItemKey == "" {
Expand Down Expand Up @@ -215,11 +215,11 @@ func (c *Client) BatchModifyDictionaryItems(i *BatchModifyDictionaryItemsInput)
}

if i.DictionaryID == "" {
return ErrMissingDictionary
return ErrMissingDictionaryID
}

if len(i.Items) > BatchModifyMaximumOperations {
return ErrBatchUpdateMaximumOperationsExceeded
return ErrMaxExceededItems
}

path := fmt.Sprintf("/service/%s/dictionary/%s/items", i.ServiceID, i.DictionaryID)
Expand Down Expand Up @@ -255,7 +255,7 @@ func (c *Client) DeleteDictionaryItem(i *DeleteDictionaryItemInput) error {
}

if i.DictionaryID == "" {
return ErrMissingDictionary
return ErrMissingDictionaryID
}

if i.ItemKey == "" {
Expand Down
19 changes: 10 additions & 9 deletions fastly/dictionary_item_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_DictionaryItems(t *testing.T) {

Expand Down Expand Up @@ -125,7 +127,7 @@ func TestClient_ListDictionaryItems_validation(t *testing.T) {
ServiceID: "foo",
DictionaryID: "",
})
if err != ErrMissingDictionary {
if err != ErrMissingDictionaryID {
t.Errorf("bad error: %s", err)
}
}
Expand All @@ -143,7 +145,7 @@ func TestClient_CreateDictionaryItem_validation(t *testing.T) {
ServiceID: "foo",
DictionaryID: "",
})
if err != ErrMissingDictionary {
if err != ErrMissingDictionaryID {
t.Errorf("bad error: %s", err)
}
}
Expand All @@ -161,7 +163,7 @@ func TestClient_GetDictionaryItem_validation(t *testing.T) {
ServiceID: "foo",
DictionaryID: "",
})
if err != ErrMissingDictionary {
if err != ErrMissingDictionaryID {
t.Errorf("bad error: %s", err)
}

Expand All @@ -188,7 +190,7 @@ func TestClient_UpdateDictionaryItem_validation(t *testing.T) {
ServiceID: "foo",
DictionaryID: "",
})
if err != ErrMissingDictionary {
if err != ErrMissingDictionaryID {
t.Errorf("bad error: %s", err)
}

Expand All @@ -215,7 +217,7 @@ func TestClient_DeleteDictionaryItem_validation(t *testing.T) {
ServiceID: "foo",
DictionaryID: "",
})
if err != ErrMissingDictionary {
if err != ErrMissingDictionaryID {
t.Errorf("bad error: %s", err)
}

Expand All @@ -241,7 +243,7 @@ func TestClient_BatchModifyDictionaryItem_validation(t *testing.T) {
ServiceID: "foo",
DictionaryID: "",
})
if err != ErrMissingDictionary {
if err != ErrMissingDictionaryID {
t.Errorf("bad error: %s", err)
}

Expand All @@ -251,8 +253,7 @@ func TestClient_BatchModifyDictionaryItem_validation(t *testing.T) {
DictionaryID: "bar",
Items: oversizedDictionaryItems,
})
if err != ErrBatchUpdateMaximumOperationsExceeded {
if err != ErrMaxExceededItems {
t.Errorf("bad error: %s", err)
}

}
4 changes: 3 additions & 1 deletion fastly/dictionary_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_Dictionaries(t *testing.T) {
t.Parallel()
Expand Down
4 changes: 3 additions & 1 deletion fastly/diff_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_Diff(t *testing.T) {
t.Parallel()
Expand Down
4 changes: 3 additions & 1 deletion fastly/digitalocean_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_DigitalOceans(t *testing.T) {
t.Parallel()
Expand Down
4 changes: 3 additions & 1 deletion fastly/director_backend_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_DirectorBackends(t *testing.T) {
t.Parallel()
Expand Down
4 changes: 3 additions & 1 deletion fastly/director_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_Directors(t *testing.T) {
t.Parallel()
Expand Down
4 changes: 3 additions & 1 deletion fastly/domain_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fastly

import "testing"
import (
"testing"
)

func TestClient_Domains(t *testing.T) {
t.Parallel()
Expand Down
Loading