Перекрестная обработка исключений с помощью веб-командлетов Powershell - PullRequest
0 голосов
/ 20 мая 2018

У меня есть модуль PowerShell, который работает с Windows PowerShell 5.1.Это сильно зависит от командлетов Invoke-WebRequest и Invoke-RestMethod, которые имеют некоторые довольно значительные изменения между 5.1 и PowerShell Core 6.

Мне уже удалось заставить большую часть кода работать между выпусками (Desktop / Core), но последнее, с чем у меня возникают проблемы, - это обработка исключений, возникающих при ответах на ошибки HTTP.Существующий код выглядит более или менее следующим образом.

try {
    $response = Invoke-WebRequest @myparams -EA Stop
    # do more stuff with the response
} catch [System.Net.WebException] {
    # parse the JSON response body for error details
}

Я не обязательно хочу перехватывать любые исключения, кроме тех, которые генерируются из-за сбоя кодов ответов HTTP с сервера.Тип исключения, возвращаемый в редакции Core, отличается от версии для настольных компьютеров и требует отдельных путей кода для анализа ответа.Итак, изначально я попробовал это:

try {
    $response = Invoke-WebRequest @myparams -EA Stop
    # do more stuff with the response
} catch [System.Net.WebException] {
    # Desktop: parse the JSON response body for error details
} catch [Microsoft.PowerShell.Commands.HttpResponseException] {
    # Core: parse the JSON response body for error details
}

Это прекрасно работает при работе в Core.Но при запуске в Desktop я получаю ошибку Unable to find type [Microsoft.PowerShell.Commands.HttpResponseException].

Какой лучший способ обойти это?Нужно ли просто перехватывать все исключения, сопоставлять строки в типе и повторно выдавать то, что мне не нужно?Есть ли более элегантный способ, который мне не хватает, который не предусматривает выпуск отдельных версий модуля для настольных и базовых версий PowerShell?

1 Ответ

0 голосов
/ 20 мая 2018

Я мог бы порекомендовать вам создать тонкую оболочку для командлетов, выполняющих обработку исключений, и, возможно, вы создадите собственный согласованный класс исключений, и каждая версия выдает один и тот же.

Во время выполнения вы определяетевашей версии / издания и установите псевдоним, который вы хотите использовать.

Пример:

function Invoke-PS51WebRequest {
[CmdletBinding()]
param(...)

    try {
        Invoke-WebRequest @PSBoundParameters -EA Stop
        # return the response
    } catch [System.Net.WebException] {
        # create a new exception
        throw [My.Custom.Exception]$_
    }
}

function Invoke-PS6XWebRequest {
[CmdletBinding()]
param(...)

    try {
        Invoke-WebRequest @PSBoundParameters -EA Stop
        # return the response
    } catch [System.Net.WebException] {
        # Desktop
        throw [My.Custom.Exception]$_
    } catch [Microsoft.PowerShell.Commands.HttpResponseException] {
        # Core
        throw [My.Custom.Exception]$_
    }
}

switch ($PSVersionTable)
{
    { $_.Is51 } { Set-Alias -Name Invoke-WebRequest -Value Invoke-PS51WebRequest -Force }
    { $_.Is6X } { Set-Alias -Name Invoke-WebRequest -Value Invoke-PS6XWebRequest -Force }
}

try {
    Invoke-WebRequest @myParams -ErrorAction Stop
} catch [My.Custom.Exception] {
    # do something
}

Это требует много работы (правильный синтаксический анализ исключений, возможно, создание более2 из этих вариантов, определяющих, на какой платформе вы находитесь на самом деле, как $PSversionTable.Is51 и .Is6X, не являются реальными, создаете свой собственный класс исключений, создаете надлежащий его экземпляр вместо приведения к нему $_ и т. Д.).

Я также продемонстрировал переопределение действительного имени Invoke-WebRequest, но я рекомендую использовать собственное имя Invoke-MyCustomWebRequest и использовать его во всем коде.Это сделает вещи более управляемыми.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...