Skip to content

Original Response Body Unattainable from Web Cmdltes on Non-Success Status Codes #5555

@markekraus

Description

@markekraus

When a non-success status code is returned the web cmdlets provide a convenient error message and attaches the HttpResponseMessage object to the Response property of the exception. In 5.1 cmdltes which wrap Invoke-RestMethod and Invoke-WebRequest could run the following to retrieve the raw response body:

try {
    Invoke-WebRequest 'http://httpbin.org/status/418' -ErrorAction Stop
}
Catch {
    $err = $_
}
$Stream = $err.Exception.Response.GetResponseStream()
$Stream.Position = 0
$Reader = [System.IO.StreamReader]::new($Stream)
$Reader.ReadToEnd()

This is needed because sometimes the response body for error codes contain useful information about why something failed.

In 6.0.0 the equivalent code is below in the "Steps to Reproduce", This would work except that the web cmdltes are disposing the stream after creating the error message:

This makes it impossible to get the original stream. This would probably not be a problem except that there are encoding issues to consider and that the string in the error message is doctored to make it more human readable:

detailMsg = System.Text.RegularExpressions.Regex.Replace(reader.ReadToEnd(), "<[^>]*>","");

I recommend not disposing the streamreader and let it naturally fall out of scope as there does not appear to be a way to dispose of a streamreader without closing the underlying stream.

Steps to reproduce

try {
    Invoke-WebRequest 'http://httpbin.org/status/418' -ErrorAction Stop
}
Catch {
    $err = $_
}
$Stream = $err.Exception.Response.Content.ReadAsStreamAsync().GetAwaiter().GetResult()
$Stream.Position = 0
$Reader = [System.IO.StreamReader]::new($Stream)
$Reader.ReadToEnd()

Expected behavior

    -=[ teapot ]=-

       _...._
     .'  _ _ `.
    | ."` ^ `". _,
    \_;`"---"`|//
      |       ;/
      \_     _/
        `"""`

Actual behavior

Exception calling ".ctor" with "1" argument(s): "Stream was not readable."
At line:1 char:1
+ $Reader = [System.IO.StreamReader]::new($Stream)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentException
You cannot call a method on a null-valued expression.
At line:1 char:1
+ $Reader.ReadToEnd()
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull

Environment data

Name                           Value
----                           -----
PSVersion                      6.0.0-rc
PSEdition                      Core
GitCommitId                    v6.0.0-rc
OS                             Microsoft Windows 10.0.15063
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Enhancementthe issue is more of a feature request than a bugResolution-FixedThe issue is fixed.WG-Cmdlets-Utilitycmdlets in the Microsoft.PowerShell.Utility module

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions