return HTTP response for error status as part of exception (#3201)

This commit is contained in:
Steve Lee 2017-02-24 22:29:11 -08:00 committed by Dongbo Wang
parent 21c8a90cc1
commit c74b2a7670
3 changed files with 84 additions and 2 deletions

View File

@ -19,6 +19,27 @@ using System.Xml;
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,7 +368,6 @@ namespace Microsoft.PowerShell.Commands
WriteVerbose(reqVerboseMsg);
HttpResponseMessage response = GetResponse(client, request);
response.EnsureSuccessStatusCode();
string contentType = ContentHelper.GetContentType(response);
string respVerboseMsg = string.Format(CultureInfo.CurrentCulture,
@ -355,6 +375,39 @@ namespace Microsoft.PowerShell.Commands
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 = "";
StreamReader reader = null;
try
{
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
}
finally
{
if (reader != null)
{
reader.Dispose();
}
}
if (!String.IsNullOrEmpty(detailMsg))
{
er.ErrorDetails = new ErrorDetails(detailMsg);
}
ThrowTerminatingError(er);
}
ProcessResponse(response);
UpdateSession(response);
@ -542,4 +595,4 @@ namespace Microsoft.PowerShell.Commands
#endregion Helper Methods
}
}
#endif
#endif

View File

@ -210,4 +210,7 @@
<data name="JsonDeserializationFailed" xml:space="preserve">
<value>Conversion from JSON failed with error: {0}</value>
</data>
<data name="ResponseStatusCodeFailure" xml:space="preserve">
<value>Response status code does not indicate success: {0} ({1}).</value>
</data>
</root>

View File

@ -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
$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
}
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" {