GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Invoke-RestMethod should return the full error response from the remote endpoint · Issue #2193 · PowerShell/PowerShell

Invoke-RestMethod should return the full error response from the remote endpoint #2193

New issue
Copy link
New issue
Copy link
Closed
Closed
Invoke-RestMethod should return the full error response from the remote endpoint#2193
Copy link
Assignees
SteveL-MSFT
Labels
Committee-ReviewedPS-Committee has reviewed this and made a decisionPS-Committee has reviewed this and made a decisionIssue-Enhancementthe issue is more of a feature request than a bugthe issue is more of a feature request than a bugResolution-FixedThe issue is fixed.The issue is fixed.WG-Cmdletsgeneral cmdlet issuesgeneral cmdlet issues
Milestone
6.0.0-beta1

Description

@1RedOne
Stephen Owen (1RedOne)
opened on Sep 6, 2016
Issue body actions

Steps to reproduce

Today, if you use Invoke-RestMethod and have any sort of malformed data in your request, Invoke-RestMethod eats the server response and instead returns a generic PowerShell error message, greatly increasing pain when troubleshooting.

As an example of desired behavior, it would be good if PowerShell surfaced the remote server response instead of just writing an error and dumping the response.

Expected behavior

It would be wonderful if Invoke-RestMethod wrote to an alternate stream or provided rich error data when encountering an error with an endpoint.

For example. note the error data I'm about to get when I used the very useful Failure function provided in this blog post, I'm able to see the full remote server response, which makes troubleshooting this an absolute breeze.

function Failure {
$global:helpme = $body
$global:helpmoref = $moref
$global:result = $_.Exception.Response.GetResponseStream()
$global:reader = New-Object System.IO.StreamReader($global:result)
$global:responseBody = $global:reader.ReadToEnd();
Write-Host -BackgroundColor:Black -ForegroundColor:Red "Status: A system exception was caught."
Write-Host -BackgroundColor:Black -ForegroundColor:Red $global:responsebody
Write-Host -BackgroundColor:Black -ForegroundColor:Red "The request body has been saved to `$global:helpme"
break
}

With this function loaded in memory, I'll run the below code with try/catch and call Failure on error.

$Splat = @{
    Method      = 'PUT'
    Uri         = 'https://api.us.onelogin.com/api/1/users/27697924/add_roles'
    ContentType = "application/json"
    Headers     = @{authorization = "bearer:$token" }
    Body        = @{role_id_array = (143175)}
}

PS C:\git> Invoke-RestMethod @Splat

Status: A system exception was caught.
{"status":{"error":true,"code":400,"type":"bad request","message":"role_id_array should be -\u003e array of positive integers"}}
The request body has been saved to $global:helpme

Actual behavior

In today's PowerShell, all server response data from Invoke-RestMethod is eaten and a generic PowerShell error is presented. In scouring the results from $error[0] I was unable to find the actual server response.

$Splat = @{
    Method      = 'PUT'
    Uri         = 'https://api.us.onelogin.com/api/1/users/27697924/add_roles'
    ContentType = "application/json"
    Headers     = @{authorization = "bearer:$token" }
    Body        = @{role_id_array = (143175)}
}

PS C:\git> Invoke-RestMethod @Splat
Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
At line:1 char:1
+ Invoke-RestMethod @Splat
+ ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Environment data

> $PSVersionTable


Name                           Value                                                                                                                                                                                                                             
----                           -----                                                                                                                                                                                                                             
PSVersion                      5.1.14393.103                                                                                                                                                                                                                     
PSEdition                      Desktop                                                                                                                                                                                                                           
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                                                                                                                                           
BuildVersion                   10.0.14393.103                                                                                                                                                                                                                    
CLRVersion                     4.0.30319.42000                                                                                                                                                                                                                   
WSManStackVersion              3.0                                                                                                                                                                                                                               
PSRemotingProtocolVersion      2.3                                                                                                                                                                                                                               
SerializationVersion           1.1.0.1                                                                                                                                                                                                                           


Reacted by Matt McNabb, Nicholas M. Getchell, Dennis Brunner, Warren Frame, Brian Scholer, Nick Bradford, Mikhail Plavskiy, Christopher Riddersäter, Marco Mangiante, Kev Maitland and 9 more

Activity

  1. Joey Aiello (joeyaiello)
    added
    Issue-BugIssue has been identified as a bug in the productIssue has been identified as a bug in the product
    WG-Cmdletsgeneral cmdlet issuesgeneral cmdlet issues
    on Sep 6, 2016
  2. mattmcnabb commented on Sep 7, 2016

    @mattmcnabb
    Matt McNabb (mattmcnabb)
    on Sep 7, 2016
    More actions

    Excellent write-up Stephen! I can second Stephen's frustration with this issue!

  3. ngetchell commented on Sep 7, 2016

    @ngetchell
    Nicholas M. Getchell (ngetchell)
    on Sep 7, 2016
    More actions

    I've definitely been bitten by this.

  4. AWahlqvist commented on Sep 7, 2016

    @AWahlqvist
    Anders Wahlqvist (AWahlqvist)
    on Sep 7, 2016
    More actions

    Same as the above, also using a helper function to get the error response stream. Hope the fix doesn't break those modules though, but even if it does it would be worth it not having to deal with it everytime.

    Great write-up!

  5. Steve Lee (SteveL-MSFT)
    added this to the This milestone has been deleted milestone on Nov 2, 2016
  6. Steve Lee (SteveL-MSFT)
    modified the milestones: This milestone has been deleted, This milestone has been deleted on Dec 19, 2016
  7. Steve Lee (SteveL-MSFT)
    self-assigned this
    on Jan 31, 2017
  8. Steve Lee (SteveL-MSFT)
    added
    Issue-Enhancementthe issue is more of a feature request than a bugthe issue is more of a feature request than a bug
    and removed
    Issue-BugIssue has been identified as a bug in the productIssue has been identified as a bug in the product
    on Feb 11, 2017
  9. vors commented on Feb 11, 2017

    @vors
    sergei (vors)
    on Feb 11, 2017
    Collaborator
    More actions

    Essentially, if we just remove one line

    response.EnsureSuccessStatusCode();
    

    PowerShell/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/CoreCLR/WebRequestPSCmdlet.CoreClr.cs

    Line 350 in aa764dd

    response.EnsureSuccessStatusCode();

    we will get a pretty decent output.
    For example:

         Reading web response                                                                                                                                          StatusCode        : 400e stream... (Number of bytes read: 229)                                                                                                     StatusDescription : BadRequest                                                                                                                                     Content           : Error in call to API function "team/get_info": Bad HTTP "Content-Type" header: "application/x-www-form-urlencoded".  Expecting one of 
                        "application/json", "application/json; charset=utf-8", "text/plain...
    RawContent        : HTTP/1.1 400 BadRequest
                        Server: nginx
                        Date: Sat, 11 Feb 2017 06:39:47 GMT
                        Connection: keep-alive
                        User-Agent: 
                        
                        Error in call to API function "tea...
    Forms             : 
    Headers           : {[Server, System.String[]], [Date, System.String[]], [Connection, System.String[]], [User-Agent, System.String[]]...}
    Images            : {}
    InputFields       : {}
    Links             : {}
    ParsedHtml        : 
    RawContentLength  : 229
    
    Reacted by Stephen Owen
  10. vors commented on Feb 11, 2017

    @vors
    sergei (vors)
    on Feb 11, 2017
    Collaborator
    More actions

    Btw, in the FullCLR version there is no call to it.

  11. Steve Lee (SteveL-MSFT)
    added
    Review - CommitteeThe PR/Issue needs a review from the PowerShell CommitteeThe PR/Issue needs a review from the PowerShell Committee
    and removed
    Review - CommitteeThe PR/Issue needs a review from the PowerShell CommitteeThe PR/Issue needs a review from the PowerShell Committee
    on Feb 11, 2017
  12. SteveL-MSFT commented on Feb 13, 2017

    @SteveL-MSFT
    Steve Lee (SteveL-MSFT)
    on Feb 13, 2017
    Member
    More actions

    Here's the experience I have coded up, feedback welcome:

    PS /home/steve/repos/PowerShell> invoke-webrequest http://httpstat.us/418       
    invoke-webrequest : 418 I'm a teapot
    At line:1 char:1
    + invoke-webrequest http://httpstat.us/418
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (Method: GET, Re...rShell/6.0. 
       0
    }:HttpRequestMessage) [Invoke-WebRequest], I'm a teapot
        + FullyQualifiedErrorId : 418,Microsoft.PowerShell.Commands.InvokeWebReque 
       stCommand
    PS /home/steve/repos/PowerShell> $e.FullyQualifiedErrorId                       
    418,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
    Reacted by Joey Aiello and Matt McNabb
  13. SteveL-MSFT commented on Feb 14, 2017

    @SteveL-MSFT
    Steve Lee (SteveL-MSFT)
    on Feb 14, 2017
    Member
    More actions

    The content of the response is stuffed into the Message property of the ErrorDetail and the HTTP Status Code is in the front of the FullyQualifiedErrorId. Response headers are thrown away (not sure if there's any useful case when you receive an error from the server).

  14. vors commented on Feb 15, 2017

    @vors
    sergei (vors)
    on Feb 15, 2017
    Collaborator
    More actions

    HTTP Status Code is in the front of the FullyQualifiedErrorId

    Not sure that's a good idea.

  15. SteveL-MSFT commented on Feb 15, 2017

    @SteveL-MSFT
    Steve Lee (SteveL-MSFT)
    on Feb 15, 2017
    Member
    More actions

    sergei (@vors), open to suggestions. Could prefix with HttpStatus, but then it's more parsing for scripts that want the actual code

  16. joeyaiello commented on Feb 16, 2017

    @joeyaiello
    Joey Aiello (joeyaiello)
    on Feb 16, 2017
    Contributor
    More actions

    @PowerShell/powershell-committee (subset of Hemant Mahawar (@HemantMahawar) Jason Shirk (@lzybkr) Kenneth Hansen (@khansen00) and myself) think that the most important piece is that you're able to get at the Response property of the exception as you can in FullCLR:

    When running Invoke-WebRequest http://httpstat.us/418, the behavior currently differs between Core and Full:

    FullCLR:

    PS C:\Users\jaiello> $error[1].exception.response
    
    
    IsMutuallyAuthenticated : False
    Cookies                 : {ARRAffinity=ce89bc5d89e3eae7a38e90a2582b973f890225b3bddc47e95c77a1d7831a8a71}
    Headers                 : {X-AspNetMvc-Version, Access-Control-Allow-Origin, Content-Length, Cache-Control...}
    SupportsHeaders         : True
    ContentLength           : 16
    ContentEncoding         :
    ContentType             : text/plain; charset=utf-8
    CharacterSet            : utf-8
    Server                  : Microsoft-IIS/8.0
    LastModified            : 2/15/2017 4:16:36 PM
    StatusCode              : 418
    StatusDescription       : I'm a teapot
    ProtocolVersion         : 1.1
    ResponseUri             : http://httpstat.us/418
    Method                  : GET
    IsFromCache             : False
    

    CoreCLR:

    PS C:\Program Files\PowerShell\6.0.0.15> $error[0].exception | fl -force *
    
    
    Message        : Response status code does not indicate success: 418 (I'm a teapot).
    Data           : {}
    InnerException :
    TargetSite     : System.Net.Http.HttpResponseMessage EnsureSuccessStatusCode()
    StackTrace     :    at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
                        at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.ProcessRecord()
    HelpLink       :
    Source         : System.Net.Http
    HResult        : -2146233088
    
    Reacted by Steve Lee and Mark
  17. Joey Aiello (joeyaiello)
    added
    Committee-ReviewedPS-Committee has reviewed this and made a decisionPS-Committee has reviewed this and made a decision
    and removed
    Review - CommitteeThe PR/Issue needs a review from the PowerShell CommitteeThe PR/Issue needs a review from the PowerShell Committee
    on Feb 16, 2017
  18. SteveL-MSFT commented on Feb 24, 2017

    @SteveL-MSFT
    Steve Lee (SteveL-MSFT)
    on Feb 24, 2017
    Member
    More actions

    The experience won't be exactly the same as the coreClr types are different, but it's improved and similar:

    PS /home/steve/repos/PowerShell> invoke-webrequest http://httpstat.us/418                                     
    invoke-webrequest : Response status code does not indicate success: 418 (I'm a teapot).
    At line:1 char:1
    + invoke-webrequest http://httpstat.us/418
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (Method: GET, Re...rShell/6.0.0
    }:HttpRequestMessage) [Invoke-WebRequest], I'm a teapot
        + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCo 
       mmand
    PS /home/steve/repos/PowerShell> $error[0].exception.response                                                 
    
    
    Version             : 1.1
    Content             : System.Net.Http.StreamContent
    StatusCode          : 418
    ReasonPhrase        : I'm a teapot
    Headers             : {[Cache-Control, System.String[]], [Server, System.String[]], [X-AspNetMvc-Version, 
                          System.String[]], [X-AspNet-Version, System.String[]]...}
    RequestMessage      : Method: GET, RequestUri: 'http://httpstat.us/418', Version: 1.1, Content: <null>, 
                          Headers:
                          {
                            User-Agent: Mozilla/5.0
                            User-Agent: (Windows NT; Linux 4.4.0-64-generic #85-Ubuntu SMP Mon Feb 20 11:50:30 
                          UTC 2017; en-US)
                            User-Agent: WindowsPowerShell/6.0.0
                          }
    IsSuccessStatusCode : False
    Reacted by Nicholas M. Getchell and Matt McNabb
  19. Steve Lee (SteveL-MSFT)
    added
    Resolution-FixedThe issue is fixed.The issue is fixed.
    on Feb 25, 2017
  20. Steve Lee (SteveL-MSFT)
    closed this as completedon Feb 25, 2017
  21. abhinavsingh003 commented on Mar 14, 2019

    @abhinavsingh003
    abhinavsingh003
    on Mar 14, 2019
    More actions

    Tried another work around to capture error from a REST API is anyone is trying to capture that:

    function Failure {
                   $Message =  $_.ErrorDetails.Message;
    		$json = $Message | ConvertFrom-Json  #if error you are trying to capture is returned in json
                   Write-Host ("Message: "+ $Message)
    }
    

    With this function loaded in memory, put your try / catch around Invoke-RestMethod and call Failure on error. Hope this helps.

    Reacted by MeGoodGuy, ƘɌỈSƬƠƑ, Jayendran Arumugam, golfalot and Gregory Ott
    Reacted by MeGoodGuy and kmoninsis
    Reacted by MeGoodGuy
  22. MeGoodGuy commented on Dec 18, 2020

    @MeGoodGuy
    MeGoodGuy
    on Dec 18, 2020
    More actions

    Thanks abhinavsingh003 !

    `        Catch {
                if($_.ErrorDetails.Message) {
                    #WebResponseError
                    Write-Host $_.ErrorDetails.Message;
                } else {
                    #UsualException
                    $_
                }
    
            }`
    
    Reacted by zinwayz, shunkin and golfalot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @SteveL-MSFT
    Steve Lee (SteveL-MSFT)

Labels

Committee-ReviewedPS-Committee has reviewed this and made a decisionPS-Committee has reviewed this and made a decisionIssue-Enhancementthe issue is more of a feature request than a bugthe issue is more of a feature request than a bugResolution-FixedThe issue is fixed.The issue is fixed.WG-Cmdletsgeneral cmdlet issuesgeneral cmdlet issues

Type

No type

Projects

No projects

    Milestone

    • 6.0.0-beta1

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402520 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.