aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Majewsky <stefan.majewsky@sap.com>2023-10-23 13:01:31 +0200
committerStefan Majewsky <stefan.majewsky@sap.com>2023-10-23 13:02:10 +0200
commit1ef60b5cd32e8470806dad1c559c4953916fe6fd (patch)
tree94b5a94a1a675a8839542bd57f535c994cbd7475
parent6067bcb956c78a38b12bb8f7a3b050a03bde97f0 (diff)
downloadgo-schwift-1ef60b5cd32e8470806dad1c559c4953916fe6fd.tar.gz
add Method, Target to type UnexpectedStatusCodeError
-rw-r--r--CHANGELOG.md9
-rw-r--r--errors.go7
-rw-r--r--request.go14
-rw-r--r--tests/container_test.go5
-rw-r--r--tests/object_test.go7
5 files changed, 37 insertions, 5 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 17a55aa..67523ed 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+# v1.3.0 (TBD)
+
+New features:
+
+- The error message of `type UnexpectedStatusCodeError` now includes the
+ request method and target object name. This will make those errors more
+ plausible when returned from complex operations that involve several Swift
+ API calls.
+
# v1.2.0 (2022-10-28)
New features:
diff --git a/errors.go b/errors.go
index bee0b9f..06fa639 100644
--- a/errors.go
+++ b/errors.go
@@ -60,6 +60,8 @@ var (
// a response with the expected successful status code. The actual status code
// can be checked with the Is() function; see documentation over there.
type UnexpectedStatusCodeError struct {
+ Method string //e.g. http.MethodGet
+ Target string //either "<account>" or "$CONTAINER_NAME" or "$CONTAINER_NAME/$OBJECT_NAME"
ExpectedStatusCodes []int
ActualResponse *http.Response
ResponseBody []byte
@@ -75,6 +77,11 @@ func (e UnexpectedStatusCodeError) Error() string {
strings.Join(codeStrs, "/"),
e.ActualResponse.StatusCode,
)
+ if e.Method != "" && e.Target != "" {
+ //NOTE: Method and Target were added in a minor version change,
+ //and may not be filled if `e` was constructed outside the library.
+ msg = fmt.Sprintf("could not %s %q in Swift: %s", e.Method, e.Target, msg)
+ }
if len(e.ResponseBody) > 0 {
msg += ": " + string(e.ResponseBody)
}
diff --git a/request.go b/request.go
index 2e78f00..7b5da6d 100644
--- a/request.go
+++ b/request.go
@@ -161,12 +161,26 @@ func (r Request) Do(backend Backend) (*http.Response, error) {
return nil, err
}
return nil, UnexpectedStatusCodeError{
+ Method: r.Method,
+ Target: describeTarget(r.ContainerName, r.ObjectName),
ExpectedStatusCodes: r.ExpectStatusCodes,
ActualResponse: resp,
ResponseBody: buf,
}
}
+// Builds a value for the UnexpectedStatusCodeError.Target attribute.
+func describeTarget(containerName, objectName string) string {
+ switch {
+ case containerName == "":
+ return "<account>"
+ case objectName == "":
+ return containerName
+ default:
+ return containerName + "/" + objectName
+ }
+}
+
func drainResponseBody(r *http.Response) error {
_, err := io.Copy(io.Discard, r.Body)
if err != nil {
diff --git a/tests/container_test.go b/tests/container_test.go
index eed4906..26dcaac 100644
--- a/tests/container_test.go
+++ b/tests/container_test.go
@@ -19,6 +19,7 @@
package tests
import (
+ "fmt"
"net/http"
"testing"
@@ -40,14 +41,14 @@ func TestContainerLifecycle(t *testing.T) {
expectBool(t, exists, false)
_, err = c.Headers()
- expectError(t, err, "expected 204 response, got 404 instead")
+ expectError(t, err, fmt.Sprintf("could not HEAD %q in Swift: expected 204 response, got 404 instead", containerName))
expectBool(t, schwift.Is(err, http.StatusNotFound), true)
expectBool(t, schwift.Is(err, http.StatusNoContent), false)
//DELETE should be idempotent and not return success on non-existence, but
//OpenStack LOVES to be inconsistent with everything (including, notably, itself)
err = c.Delete(nil)
- expectError(t, err, "expected 204 response, got 404 instead: <html><h1>Not Found</h1><p>The resource could not be found.</p></html>")
+ expectError(t, err, fmt.Sprintf("could not DELETE %q in Swift: expected 204 response, got 404 instead: <html><h1>Not Found</h1><p>The resource could not be found.</p></html>", containerName))
err = c.Create(nil)
expectSuccess(t, err)
diff --git a/tests/object_test.go b/tests/object_test.go
index 2f22b24..cfcc908 100644
--- a/tests/object_test.go
+++ b/tests/object_test.go
@@ -20,6 +20,7 @@ package tests
import (
"bytes"
+ "fmt"
"io"
"net/http"
"strings"
@@ -41,14 +42,14 @@ func TestObjectLifecycle(t *testing.T) {
expectObjectExistence(t, o, false)
_, err := o.Headers()
- expectError(t, err, "expected 200 response, got 404 instead")
+ expectError(t, err, fmt.Sprintf("could not HEAD %q in Swift: expected 200 response, got 404 instead", o.FullName()))
expectBool(t, schwift.Is(err, http.StatusNotFound), true)
expectBool(t, schwift.Is(err, http.StatusNoContent), false)
//DELETE should be idempotent and not return success on non-existence, but
//OpenStack LOVES to be inconsistent with everything (including, notably, itself)
err = o.Delete(nil, nil)
- expectError(t, err, "expected 204 response, got 404 instead: <html><h1>Not Found</h1><p>The resource could not be found.</p></html>")
+ expectError(t, err, fmt.Sprintf("could not DELETE %q in Swift: expected 204 response, got 404 instead: <html><h1>Not Found</h1><p>The resource could not be found.</p></html>", o.FullName()))
err = o.Upload(bytes.NewReader([]byte("test")), nil, nil)
expectSuccess(t, err)
@@ -165,7 +166,7 @@ func TestObjectUpdate(t *testing.T) {
newHeaders.ContentType().Set("application/json")
err := obj.Update(newHeaders, nil)
expectBool(t, schwift.Is(err, http.StatusNotFound), true)
- expectError(t, err, "expected 202 response, got 404 instead: <html><h1>Not Found</h1><p>The resource could not be found.</p></html>")
+ expectError(t, err, fmt.Sprintf("could not POST %q in Swift: expected 202 response, got 404 instead: <html><h1>Not Found</h1><p>The resource could not be found.</p></html>", obj.FullName()))
//create object
err = obj.Upload(nil, nil, nil)