diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs
index 2797f92cc59..ca38c1ed3e6 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs
@@ -19,6 +19,27 @@
namespace Microsoft.PowerShell.Commands
{
+ ///
+ /// Exception class for webcmdlets to enable returning HTTP error response
+ ///
+ public sealed class HttpResponseException : HttpRequestException
+ {
+ ///
+ /// Constructor for HttpResponseException
+ ///
+ /// Message for the exception
+ /// Response from the HTTP server
+ public HttpResponseException (string message, HttpResponseMessage response) : base(message)
+ {
+ Response = response;
+ }
+
+ ///
+ /// HTTP error response
+ ///
+ public HttpResponseMessage Response { get; private set; }
+ }
+
///
/// Base class for Invoke-RestMethod and Invoke-WebRequest commands.
///
@@ -347,7 +368,6 @@ protected override void ProcessRecord()
WriteVerbose(reqVerboseMsg);
HttpResponseMessage response = GetResponse(client, request);
- response.EnsureSuccessStatusCode();
string contentType = ContentHelper.GetContentType(response);
string respVerboseMsg = string.Format(CultureInfo.CurrentCulture,
@@ -355,6 +375,39 @@ protected override void ProcessRecord()
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 @@ internal long SetRequestContent(HttpRequestMessage request, IDictionary content)
#endregion Helper Methods
}
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx
index 368e34ad7be..b7256271e95 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx
+++ b/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx
@@ -210,4 +210,7 @@
Conversion from JSON failed with error: {0}
+
+ Response status code does not indicate success: {0} ({1}).
+
\ No newline at end of file
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1
index 11529315a69..66d618ddc61 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1
@@ -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" {