1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
package http
import (
"context"
"errors"
"fmt"
"net/http"
"github.com/aws/smithy-go"
"github.com/aws/smithy-go/middleware"
)
func ExampleResponseError() {
stack := middleware.NewStack("my cool stack", NewStackRequest)
stack.Deserialize.Add(middleware.DeserializeMiddlewareFunc("wrap http response error",
func(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) (
out middleware.DeserializeOutput, metadata middleware.Metadata, err error,
) {
out, metadata, err = next.HandleDeserialize(ctx, in)
if err == nil {
// Nothing to do when there is no error.
return out, metadata, err
}
rawResp, ok := out.RawResponse.(*Response)
if !ok {
// No raw response to wrap with.
return out, metadata, err
}
// Wrap the returned error with the response error containing the
// returned response.
err = &ResponseError{
Response: rawResp,
Err: err,
}
return out, metadata, err
}),
middleware.After,
)
stack.Deserialize.Add(middleware.DeserializeMiddlewareFunc("deserialize error",
func(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) (
out middleware.DeserializeOutput, metadata middleware.Metadata, err error,
) {
out, metadata, err = next.HandleDeserialize(ctx, in)
if err != nil {
return middleware.DeserializeOutput{}, metadata, err
}
rawResp := out.RawResponse.(*Response)
if rawResp.StatusCode == 200 {
return out, metadata, nil
}
// Deserialize the response API error values.
err = &smithy.GenericAPIError{
Code: rawResp.Header.Get("Error-Code"),
Message: rawResp.Header.Get("Error-Message"),
}
return out, metadata, err
}),
middleware.After,
)
// Mock example handler taking the request input and returning a response
mockHandler := middleware.HandlerFunc(func(ctx context.Context, in interface{}) (
output interface{}, metadata middleware.Metadata, err error,
) {
// populate the mock response with an API error and additional data.
resp := &http.Response{
StatusCode: 404,
Header: http.Header{
"Extra-Header": []string{"foo value"},
"Error-Code": []string{"FooException"},
"Error-Message": []string{"some message about the error"},
},
}
// The handler's returned response will be available as the
// DeserializeOutput.RawResponse field.
return &Response{
Response: resp,
}, metadata, nil
})
// Use the stack to decorate the handler then invoke the decorated handler
// with the inputs.
handler := middleware.DecorateHandler(mockHandler, stack)
_, _, err := handler.Handle(context.Background(), struct{}{})
if err == nil {
fmt.Printf("expect error, got none")
return
}
if err != nil {
var apiErr smithy.APIError
if errors.As(err, &apiErr) {
fmt.Printf("request failed: %s, %s\n", apiErr.ErrorCode(), apiErr.ErrorMessage())
}
var respErr *ResponseError
if errors.As(err, &respErr) {
fmt.Printf("response status: %v\n", respErr.HTTPStatusCode())
fmt.Printf("response header: %v\n", respErr.HTTPResponse().Header.Get("Extra-Header"))
}
}
// Output:
// request failed: FooException, some message about the error
// response status: 404
// response header: foo value
}
|