%: Вы не можете вызвать метод для выражения с нулевым значением - PullRequest
0 голосов
/ 06 декабря 2018

Мне кажется, я нашел необъяснимое в сценариях PowerShell.Позвольте мне описать проблему ниже:

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

function GetBugsFromVSTS($applicationName, $first_url, $second_url, $query) {
    #Building the body of the HTTP request to VSTS endpoint
    $bodyOfRequest = $query | ConvertTo-Json

    #Building headers of the HTTP request to VSTS endpoint
    $headers = @{
        'Content-Type'='application/json'
        'Accept'='application/json'
        'Authorization' = '' + $vsts_access_token + ''
    }

    $getBugs = Invoke-RestMethod -Uri $first_url `
               -Method Post `
               -Body $bodyOfRequest `
               -Headers $headers | ConvertTo-Json -Depth 100

    $json_decoded = $getBugs | ConvertFrom-Json

    if ($json_decoded.workItems -eq $null) {
        Write-Host "$applicationName Json decoded workitems are equal null" -ForegroundColor Red
    } else {
        Write-Host "$applicationName Json decoded workitems are not null" -ForegroundColor Green
        $json_decoded.workItems | % {
            $bug_id = $_.id
            Write-Host $bug_id
        }
    }

    $json_decoded.workItems | % {
        $bug_id = $_.id
        $url = ($second_url +$bug_id)

        $getVstsBugState = Invoke-RestMethod -Uri $url -Method Get -Headers $headers

        [PSCustomObject]@{
            "Application Name" = $applicationName
            "Id" = $bug_id;
            "State" = $getVstsBugState.fields.'System.State';
            "Reason" = $getVstsBugState.fields.'System.Reason';
            "Severity" = $getVstsBugState.fields.'Microsoft.VSTS.Common.Severity'.Substring(4);
            "AssignedTo" = $getVstsBugState.fields.'System.AssignedTo'.displayName
        }
    }
}

Когда я пытаюсь запустить ее

    $application = "MyBeautifulApp"
    $application_first_url = "https://test.visualstudio.com/72L80E4b-1583-45c1-b669-d8de6133V895/_apis/wit/wiql?api-version=1.0"
    $application_second_url = "https://test.visualstudio.com/72L80E4b-1583-45c1-b669-d8de6133V895/_apis/wit/workItems/"
    $application_query = @{"query" = "SELECT [System.Id],[System.WorkItemType],[System.Title],[System.AssignedTo],[System.State] FROM WorkItems WHERE [System.TeamProject] = @project AND [System.WorkItemType] = 'Bug' AND [System.Title] CONTAINS 'Test' AND [System.TAGS] CONTAINS 'Test'"}
    GetBugsFromVSTS $application $application_first_url $application_second_url $application_query
} catch {
    Write-Warning "##vso[task.logissue type=warning;]Some problem occured querying MyBeautifulApp application. Please see below for error details"
    $_
}

Самое интересное здесь - это то, что я получаю это действительно странное сообщение об ошибке

ПРЕДУПРЕЖДЕНИЕ: ## vso [task.logissue type = warning;] Возникла некоторая проблемазапрашивая приложение MyBeautifulApp.Пожалуйста, смотрите подробности ошибки ниже

%: Вы не можете вызвать метод для выражения с нулевым значением.

Ради теста я добавил предложение if..else, чтобы проверить это $json_decoded.workItems не равны нулю, и эта проверка проходит.Если я выполню код, полный вывод будет

MyBeautifulApp Json decoded workitems are not null
9805
10330
10331
10371
10372
10373
10374

WARNING: ##vso[task.logissue type=warning;]Some problem occured querying MyBeautifulApp application. Please see below for error details
% : You cannot call a method on a null-valued expression. line 29

+     $json_decoded.workItems | % {
+                               ~~~
    + CategoryInfo          : InvalidOperation: (:) [ForEach-Object], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull,Microsoft.PowerShell.Commands.ForEachObjectCommand

Как такое возможно, что первая проверка для $json_decoded.workItems ( строка 23 ) не указывает, что переменная равна нулю, тогда каквторое утверждение ( строка 29 ) показывает, что оно нулевое?

1 Ответ

0 голосов
/ 06 декабря 2018

Проблема не в $json_decoded.workItems, проблема возникает внутри блока скрипта, переданного в % / ForEach-Object:

Поскольку вы используете вложение * 1008Обработчик * / catch, к сожалению, отдельный оператор внутри блока, к сожалению, не указан в сообщении об ошибке.

Однако, учитывая, что есть только one При вызове метода в вашем блоке может быть выведена ошибочная строка:

"Severity" = $getVstsBugState.fields.'Microsoft.VSTS.Common.Severity'.Substring(4);

Другими словами: $getVstsBugState.fields.'Microsoft.VSTS.Common.Severity' оценивается как $null, поэтому вызов метода .Substring() завершается неудачей.

...