-
Notifications
You must be signed in to change notification settings - Fork 7.7k
return HTTP response for error status as part of exception #3201
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
Changes from 7 commits
0d8be7b
6fe216a
1920187
8483c7c
5dd0b5f
eaaaa7f
4a8e693
4a420db
c3c939f
4b1e21c
8fbe863
650839b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,27 @@ | |
|
||
namespace Microsoft.PowerShell.Commands | ||
{ | ||
/// <summary> | ||
/// Exception class for webcmdlets to enable returning HTTP error response | ||
/// </summary> | ||
public sealed class HttpResponseException : HttpRequestException | ||
{ | ||
/// <summary> | ||
/// Constructor for HttpResponseException | ||
/// </summary> | ||
/// <param name="message">Message for the exception</param> | ||
/// <param name="response">Response from the HTTP server</param> | ||
public HttpResponseException (string message, HttpResponseMessage response) : base(message) | ||
{ | ||
Response = response; | ||
} | ||
|
||
/// <summary> | ||
/// HTTP error response | ||
/// </summary> | ||
public HttpResponseMessage Response { get; private set; } | ||
} | ||
|
||
/// <summary> | ||
/// Base class for Invoke-RestMethod and Invoke-WebRequest commands. | ||
/// </summary> | ||
|
@@ -347,14 +368,39 @@ protected override void ProcessRecord() | |
WriteVerbose(reqVerboseMsg); | ||
|
||
HttpResponseMessage response = GetResponse(client, request); | ||
response.EnsureSuccessStatusCode(); | ||
|
||
string contentType = ContentHelper.GetContentType(response); | ||
string respVerboseMsg = string.Format(CultureInfo.CurrentCulture, | ||
"received {0}-byte response of content type {1}", | ||
response.Content.Headers.ContentLength, | ||
contentType); | ||
WriteVerbose(respVerboseMsg); | ||
|
||
if (!response.IsSuccessStatusCode) | ||
{ | ||
string message = String.Format(CultureInfo.CurrentCulture, WebCmdletStrings.ResponseStatusCodeFailure, | ||
(int)response.StatusCode, response.ReasonPhrase); | ||
HttpResponseException httpEx = new HttpResponseException(message, response); | ||
ErrorRecord er = new ErrorRecord(httpEx, "WebCmdletWebResponseException", ErrorCategory.InvalidOperation, request); | ||
string detailMsg = ""; | ||
try | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest using try-catch-finally to avoid nesting There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @2xmax do you mean like this?
|
||
{ | ||
using (StreamReader reader = new StreamReader(StreamHelper.GetResponseStream(response))) | ||
{ | ||
// remove HTML tags making it easier to read | ||
detailMsg = System.Text.RegularExpressions.Regex.Replace(reader.ReadToEnd(), "<[^>]*>",""); | ||
} | ||
} | ||
catch (Exception) | ||
{ | ||
// catch all | ||
} | ||
if (!String.IsNullOrEmpty(detailMsg)) | ||
{ | ||
er.ErrorDetails = new ErrorDetails(detai 8000 lMsg); | ||
} | ||
ThrowTerminatingError(er); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will make the change |
||
} | ||
ProcessResponse(response); | ||
UpdateSession(response); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -399,6 +399,19 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { | |
$result = ExecuteWebCommand -command $command | ||
$result.Error | Should BeNullOrEmpty | ||
} | ||
|
||
It "Validate Invoke-WebRequest returns HTTP errors in exception" { | ||
|
||
$command = "Invoke-WebRequest -Uri http://httpbin.org/status/418" | ||
$result = ExecuteWebCommand -command $command | ||
|
||
$result.Error.ErrorDetails.Message | Should Match "\-=\[ teapot \]" | ||
$result.Error.Exception | Should BeOfType Microsoft.PowerShell.Commands.HttpResponseException | ||
$result.Error.Exception.Response.StatusCode | Should Be 418 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we test for Exception.Headers and Exception.Status too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Those are getting removed |
||
$result.Error.Exception.Response.ReasonPhrase | Should Be "I'm a teapot" | ||
$result.Error.Exception.Message | Should Match ": 418 \(I'm a teapot\)\." | ||
$result.Error.FullyQualifiedErrorId | Should Be "WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand" | ||
} | ||
} | ||
|
||
Describe "Invoke-RestMethod tests" -Tags "Feature" { | ||
|
@@ -642,6 +655,19 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { | |
$result = ExecuteWebCommand -command $command | ||
$result.Error | Should BeNullOrEmpty | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pls add a test with a response content There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will do |
||
It "Validate Invoke-RestMethod returns HTTP errors in exception" { | ||
|
||
$command = "Invoke-RestMethod -Uri http://httpbin.org/status/418" | ||
$result = ExecuteWebCommand -command $command | ||
|
||
$result.Error.ErrorDetails.Message | Should Match "\-=\[ teapot \]" | ||
$result.Error.Exception | Should BeOfType Microsoft.PowerShell.Commands.HttpResponseException | ||
$result.Error.Exception.Response.StatusCode | Should Be 418 | ||
$result.Error.Exception.Response.ReasonPhrase | Should Be "I'm a teapot" | ||
$result.Error.Exception.Message | Should Match ": 418 \(I'm a teapot\)\." | ||
$result.Error.FullyQualifiedErrorId | Should Be "WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand" | ||
} | ||
} | ||
|
||
Describe "Validate Invoke-WebRequest and Invoke-RestMethod -InFile" -Tags "Feature" { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest moving the class into a separate file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a search of the existing source and it appears that in some cases Exceptions are declared in a separate file (like SessionStateExceptions.cs), but in many other cases, the Exception is declared where it's used (like parserutils.cs).