Powershell: как получить номер строки исключения при использовании ScriptBlock::Invoke

Как я могу получить номер строки, в которой в этом примере выдается исключение? Пример ниже дает мне только номер строки, где я вызываю блок скрипта (т.е. $sb.Invoke()). Мне нужен номер строки, где я выбрасываю «Ошибка в FooBar».

function Foobar {
    throw "Error in FooBar"
}

function Bar {
    FooBar
}

function Foo {
    Bar
}

try {
        $sb = ${function:Foo}
        $sb.Invoke()
    }
catch {
    $ErrorMessage = $_.Exception.Message
    $line = $_.InvocationInfo.ScriptLineNumber
    $script_name = $_.InvocationInfo.ScriptName
    write-host "<--Error: Occurred on line $line in script $script_name." 
    Write-host "<--Error: $ErrorMessage"
}

ОБНОВИТЬ:

Если я изменю:

$sb = ${function:Foo}
$sb.Invoke()

к этому:

$func_info = get-command Foo
Invoke-Command $func_info.ScriptBlock

оно работает.


person Matthew S    schedule 16.04.2014    source источник


Ответы (1)


Это похоже на ограничение обработки ошибок Invoke() - он передает сообщение об ошибке, но отбрасывает информацию о вызове.

Одним из обходных путей является перехват и повторное создание внутри самого блока сценария, но с дополнительной информацией, например.

$sb = {
    try {
        Foo
    }
    catch {
        throw "Error: $($_.Exception.Message). Stack trace:`n$($_.ScriptStackTrace)" 
    }
}
$sb.Invoke()

Это выводит:

<--Error: Occurred on line 22 in script .
<--Error: Exception calling "Invoke" with "0" argument(s): "Error: Error in FooBar. Stack trace:
at Foobar, <No file>: line 2
at Bar, <No file>: line 6
at Foo, <No file>: line 10
at <ScriptBlock>, <No file>: line 16
at <ScriptBlock>, <No file>: line 22"
person ben    schedule 01.03.2016