From 774530e0b667b47c028f62e61770dba2e7aeb441 Mon Sep 17 00:00:00 2001 From: magodo Date: Tue, 26 Nov 2024 14:52:12 +1100 Subject: [PATCH 1/2] SDK LRO Poller: Rest the result.HttpResponse.Body before returning --- sdk/client/resourcemanager/poller_lro.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdk/client/resourcemanager/poller_lro.go b/sdk/client/resourcemanager/poller_lro.go index 527257c3514..dbe6a88180b 100644 --- a/sdk/client/resourcemanager/poller_lro.go +++ b/sdk/client/resourcemanager/poller_lro.go @@ -194,6 +194,7 @@ func (p *longRunningOperationPoller) Poll(ctx context.Context) (result *pollers. if parseError != nil { return nil, parseError } + result.HttpResponse.Body = io.NopCloser(bytes.NewReader(respBody)) err = pollers.PollingFailedError{ HttpResponse: result.HttpResponse, @@ -206,6 +207,7 @@ func (p *longRunningOperationPoller) Poll(ctx context.Context) (result *pollers. if parseError != nil { return nil, parseError } + result.HttpResponse.Body = io.NopCloser(bytes.NewReader(respBody)) err = pollers.PollingCancelledError{ HttpResponse: result.HttpResponse, From 2040c802ee5f42807e63061869aaf0905d1dfdbb Mon Sep 17 00:00:00 2001 From: magodo Date: Thu, 13 Mar 2025 11:44:31 +1100 Subject: [PATCH 2/2] parseErrorFromApiResponse accepts a pointer --- sdk/client/resourcemanager/errors.go | 2 +- sdk/client/resourcemanager/errors_test.go | 27 ++++++++++++++--------- sdk/client/resourcemanager/poller_lro.go | 6 ++--- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/sdk/client/resourcemanager/errors.go b/sdk/client/resourcemanager/errors.go index 942ded03662..35a5a2909ff 100644 --- a/sdk/client/resourcemanager/errors.go +++ b/sdk/client/resourcemanager/errors.go @@ -43,7 +43,7 @@ API Response: // parseErrorFromApiResponse parses the error from the API Response // into an Error type, which allows for better surfacing of errors -func parseErrorFromApiResponse(response http.Response) (*Error, error) { +func parseErrorFromApiResponse(response *http.Response) (*Error, error) { respBody, err := io.ReadAll(response.Body) if err != nil { return nil, fmt.Errorf("parsing response body: %+v", err) diff --git a/sdk/client/resourcemanager/errors_test.go b/sdk/client/resourcemanager/errors_test.go index 251e2575374..9198d3b5550 100644 --- a/sdk/client/resourcemanager/errors_test.go +++ b/sdk/client/resourcemanager/errors_test.go @@ -24,7 +24,7 @@ func TestParseErrorFromApiResponse_LongRunningOperation(t *testing.T) { Message: "The specified name is already in use.", Status: "Failed", } - actual, err := parseErrorFromApiResponse(input) + actual, err := parseErrorFromApiResponse(&input) if err != nil { t.Fatalf("parsing error from api response: %+v", err) } @@ -34,6 +34,13 @@ func TestParseErrorFromApiResponse_LongRunningOperation(t *testing.T) { if !reflect.DeepEqual(*actual, expected) { t.Fatalf("expected and actual didn't match. Expected: %+v\n\n Actual: %+v", expected, actual) } + b, err := io.ReadAll(input.Body) + if err != nil { + t.Fatalf("reading the response body after parsing: %v", err) + } + if !reflect.DeepEqual(string(b), body) { + t.Fatalf("expected and actual didn't match. Expected: %+v\n\n Actual: %+v", body, string(b)) + } } func TestParseErrorFromApiResponse_ResourceManagerType1(t *testing.T) { @@ -49,7 +56,7 @@ func TestParseErrorFromApiResponse_ResourceManagerType1(t *testing.T) { Message: "Cannot update the site 'func-tfbug-b78d100425' because it uses AlwaysOn feature which is not allowed in the target compute mode.", Status: "Unknown", } - actual, err := parseErrorFromApiResponse(input) + actual, err := parseErrorFromApiResponse(&input) if err != nil { t.Fatalf("parsing error from api response: %+v", err) } @@ -74,7 +81,7 @@ func TestParseErrorFromApiResponse_ResourceManagerType2(t *testing.T) { Message: "Failed to start operation. Verify input and try operation again.\nFailed to start operation. Verify input and try operation again.\nPossible Causes: \"Invalid parameters were specified.\"\nRecommended Action: \"Verify the input and try again.\"", Status: "BadRequest", } - actual, err := parseErrorFromApiResponse(input) + actual, err := parseErrorFromApiResponse(&input) if err != nil { t.Fatalf("parsing error from api response: %+v", err) } @@ -98,7 +105,7 @@ func TestParseErrorFromApiResponse_ResourceManagerType2Alt(t *testing.T) { Message: "The request is not valid.\nResource name is not valid. It must be between 3 and 26 characters and can only include alphanumeric characters and hyphens.", Status: "ValidationError", } - actual, err := parseErrorFromApiResponse(input) + actual, err := parseErrorFromApiResponse(&input) if err != nil { t.Fatalf("parsing error from api response: %+v", err) } @@ -123,7 +130,7 @@ func TestParseErrorFromApiResponse_ResourceManagerType3(t *testing.T) { Message: "Outbound Trust/Untrust certificate can not be deleted from rule stack SUBSCRIPTION~XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXX~RG~acctestRG-PAN-230725055238618023~STACK~testAcc-palrs-230725055238618023 as associated rule list(s) already has SSL outbound inspection set with status code BadRequest", Status: "Failed", } - actual, err := parseErrorFromApiResponse(input) + actual, err := parseErrorFromApiResponse(&input) if err != nil { t.Fatalf("parsing error from api response: %+v", err) } @@ -147,7 +154,7 @@ func TestParseErrorFromApiResponse_EmptyResponseShouldOutputHttpResponseAnyway(t Message: "Couldn't parse Azure API Response into a friendly error - please see the original HTTP Response for more details (and file a bug so we can fix this!).", Status: "Unknown", } - actual, err := parseErrorFromApiResponse(input) + actual, err := parseErrorFromApiResponse(&input) if err != nil { t.Fatalf("parsing error from api response: %+v", err) } @@ -172,7 +179,7 @@ func TestParseErrorFromApiResponse_UnexpectedHtmlShouldOutputHttpResponseAnyway( Message: "Couldn't parse Azure API Response into a friendly error - please see the original HTTP Response for more details (and file a bug so we can fix this!).", Status: "Unknown", } - actual, err := parseErrorFromApiResponse(input) + actual, err := parseErrorFromApiResponse(&input) if err != nil { t.Fatalf("parsing error from api response: %+v", err) } @@ -197,7 +204,7 @@ func TestParseErrorFromApiResponse_UnexpectedLiteralStringShouldOutputHttpRespon Message: "Couldn't parse Azure API Response into a friendly error - please see the original HTTP Response for more details (and file a bug so we can fix this!).", Status: "Unknown", } - actual, err := parseErrorFromApiResponse(input) + actual, err := parseErrorFromApiResponse(&input) if err != nil { t.Fatalf("parsing error from api response: %+v", err) } @@ -222,7 +229,7 @@ func TestParseErrorFromApiResponse_UnexpectedLiteralQuotedStringShouldOutputHttp Message: "Couldn't parse Azure API Response into a friendly error - please see the original HTTP Response for more details (and file a bug so we can fix this!).", Status: "Unknown", } - actual, err := parseErrorFromApiResponse(input) + actual, err := parseErrorFromApiResponse(&input) if err != nil { t.Fatalf("parsing error from api response: %+v", err) } @@ -246,7 +253,7 @@ func TestParseErrorFromApiResponse_UnexpectedShouldOutputHttpResponseAnyway(t *t Message: "Couldn't parse Azure API Response into a friendly error - please see the original HTTP Response for more details (and file a bug so we can fix this!).", Status: "Unknown", } - actual, err := parseErrorFromApiResponse(input) + actual, err := parseErrorFromApiResponse(&input) if err != nil { t.Fatalf("parsing error from api response: %+v", err) } diff --git a/sdk/client/resourcemanager/poller_lro.go b/sdk/client/resourcemanager/poller_lro.go index dbe6a88180b..506c7a11133 100644 --- a/sdk/client/resourcemanager/poller_lro.go +++ b/sdk/client/resourcemanager/poller_lro.go @@ -190,11 +190,10 @@ func (p *longRunningOperationPoller) Poll(ctx context.Context) (result *pollers. } if result.Status == pollers.PollingStatusFailed { - lroError, parseError := parseErrorFromApiResponse(*result.HttpResponse.Response) + lroError, parseError := parseErrorFromApiResponse(result.HttpResponse.Response) if parseError != nil { return nil, parseError } - result.HttpResponse.Body = io.NopCloser(bytes.NewReader(respBody)) err = pollers.PollingFailedError{ HttpResponse: result.HttpResponse, @@ -203,11 +202,10 @@ func (p *longRunningOperationPoller) Poll(ctx context.Context) (result *pollers. } if result.Status == pollers.PollingStatusCancelled { - lroError, parseError := parseErrorFromApiResponse(*result.HttpResponse.Response) + lroError, parseError := parseErrorFromApiResponse(result.HttpResponse.Response) if parseError != nil { return nil, parseError } - result.HttpResponse.Body = io.NopCloser(bytes.NewReader(respBody)) err = pollers.PollingCancelledError{ HttpResponse: result.HttpResponse,