pagination error types
diff --git a/errors.go b/errors.go
index 62af11c..e790196 100644
--- a/errors.go
+++ b/errors.go
@@ -244,3 +244,14 @@
func (e ErrMultipleResourcesFound) Error() string {
return fmt.Sprintf("Found %d %ss matching %s", e.Count, e.ResourceType, e.Name)
}
+
+// ErrUnexpectedType is the error when an unexpected type is encountered
+type ErrUnexpectedType struct {
+ BaseError
+ Expected string
+ Actual string
+}
+
+func (e ErrUnexpectedType) Error() string {
+ return fmt.Sprintf("Expected %s but got %s", e.Expected, e.Actual)
+}
diff --git a/pagination/linked.go b/pagination/linked.go
index 431464b..3656fb7 100644
--- a/pagination/linked.go
+++ b/pagination/linked.go
@@ -3,6 +3,8 @@
import (
"fmt"
"reflect"
+
+ "github.com/gophercloud/gophercloud"
)
// LinkedPageBase may be embedded to implement a page that provides navigational "Next" and "Previous" links within its result.
@@ -31,7 +33,10 @@
submap, ok := current.Body.(map[string]interface{})
if !ok {
- return "", fmt.Errorf("Expected an object, but was %#v", current.Body)
+ err := gophercloud.ErrUnexpectedType{}
+ err.Expected = "map[string]interface{}"
+ err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body))
+ return "", err
}
for {
@@ -45,7 +50,10 @@
if len(path) > 0 {
submap, ok = value.(map[string]interface{})
if !ok {
- return "", fmt.Errorf("Expected an object, but was %#v", value)
+ err := gophercloud.ErrUnexpectedType{}
+ err.Expected = "map[string]interface{}"
+ err.Actual = fmt.Sprintf("%v", reflect.TypeOf(value))
+ return "", err
}
} else {
if value == nil {
@@ -55,7 +63,10 @@
url, ok := value.(string)
if !ok {
- return "", fmt.Errorf("Expected a string, but was %#v", value)
+ err := gophercloud.ErrUnexpectedType{}
+ err.Expected = "string"
+ err.Actual = fmt.Sprintf("%v", reflect.TypeOf(value))
+ return "", err
}
return url, nil
@@ -63,11 +74,15 @@
}
}
+// IsEmpty satisifies the IsEmpty method of the Page interface
func (current LinkedPageBase) IsEmpty() (bool, error) {
if b, ok := current.Body.([]interface{}); ok {
return len(b) == 0, nil
}
- return true, fmt.Errorf("Error while checking if LinkedPageBase was empty: expected []interface type for Body bot got %+v", reflect.TypeOf(current.Body))
+ err := gophercloud.ErrUnexpectedType{}
+ err.Expected = "[]interface{}"
+ err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body))
+ return true, err
}
// GetBody returns the linked page's body. This method is needed to satisfy the
diff --git a/pagination/marker.go b/pagination/marker.go
index 26b9d97..52e53ba 100644
--- a/pagination/marker.go
+++ b/pagination/marker.go
@@ -3,6 +3,8 @@
import (
"fmt"
"reflect"
+
+ "github.com/gophercloud/gophercloud"
)
// MarkerPage is a stricter Page interface that describes additional functionality required for use with NewMarkerPager.
@@ -38,11 +40,15 @@
return currentURL.String(), nil
}
+// IsEmpty satisifies the IsEmpty method of the Page interface
func (current MarkerPageBase) IsEmpty() (bool, error) {
if b, ok := current.Body.([]interface{}); ok {
return len(b) == 0, nil
}
- return true, fmt.Errorf("Error while checking if MarkerPageBase was empty: expected []interface type for Body bot got %+v", reflect.TypeOf(current.Body))
+ err := gophercloud.ErrUnexpectedType{}
+ err.Expected = "[]interface{}"
+ err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body))
+ return true, err
}
// GetBody returns the linked page's body. This method is needed to satisfy the
diff --git a/pagination/pager.go b/pagination/pager.go
index ce66a04..415442f 100644
--- a/pagination/pager.go
+++ b/pagination/pager.go
@@ -202,7 +202,10 @@
body.Index(i).Set(reflect.ValueOf(s))
}
default:
- return nil, fmt.Errorf("Page body has unrecognized type.")
+ err := gophercloud.ErrUnexpectedType{}
+ err.Expected = "map[string]interface{}/[]byte/[]interface{}"
+ err.Actual = fmt.Sprintf("%v", reflect.TypeOf(testPage.GetBody()))
+ return nil, err
}
// Each `Extract*` function is expecting a specific type of page coming back,
diff --git a/pagination/single.go b/pagination/single.go
index 2be2ff6..4251d64 100644
--- a/pagination/single.go
+++ b/pagination/single.go
@@ -3,6 +3,8 @@
import (
"fmt"
"reflect"
+
+ "github.com/gophercloud/gophercloud"
)
// SinglePageBase may be embedded in a Page that contains all of the results from an operation at once.
@@ -13,11 +15,15 @@
return "", nil
}
+// IsEmpty satisifies the IsEmpty method of the Page interface
func (current SinglePageBase) IsEmpty() (bool, error) {
if b, ok := current.Body.([]interface{}); ok {
return len(b) == 0, nil
}
- return true, fmt.Errorf("Error while checking if SinglePageBase was empty: expected []interface type for Body bot got %+v", reflect.TypeOf(current.Body))
+ err := gophercloud.ErrUnexpectedType{}
+ err.Expected = "[]interface{}"
+ err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body))
+ return true, err
}
// GetBody returns the single page's body. This method is needed to satisfy the