RamblingCookieMonster / Invoke-Parallel

Speed up PowerShell with simplified multithreading
MIT License
384 stars 88 forks source link

Exception handling question #35

Closed avishnyakov closed 8 years ago

avishnyakov commented 8 years ago

Hello team,

Havign the folllowing code which raises and exception. The issue is that it is extremely hard to trace the error code, the line or the funtion once it was run with Invok-Parallel.


function RunAs-Parallel ($array, $scriptBlock) {
     $array | Invoke-Parallel -ImportVariables -ImportModules -Throttle $array.Count $scriptBlock  
}

$array = @(1,2,3,4,5,6,7,8,9,10)

RunAs-Parallel $array {

    $item = $_
    Write-Host $_

    if($item -eq 4) {

        haha $tmp

        throw "sdfds"
    }

}

The output would be like:

System.Management.Automation.CommandNotFoundException: The term 'haha' is not recognized as the name of a cmdl
et, function, script file, or operable program. Check the spelling of the name, or if a path was included, ver
ify that the path is correct and try again.

Another silly take:


try {
            #$array | Invoke-Parallel -ImportVariables -ImportModules -Throttle $array.Count $scriptBlock -Verbose -Quiet
            $array | Invoke-Parallel -ImportVariables -ImportModules -Throttle $array.Count $scriptBlock  

        }
        catch {

            Write-Host "Catching issue..."

            $allErrors = $_

            foreach($err in $allErrors) {

                Write-Host "..."

                $ex = $err.Exception;

                while($ex -ne $null)
                {
                    Write-Host "Error message:" -ForegroundColor green
                    Write-Host $ex 

                    Write-Host "Error InnerExceptiuon:" -ForegroundColor green
                    Write-Host $ex.

                    Write-Host "Error stacktrace:" -ForegroundColor green
                    Write-Host $ex.InnerException

                    Write-Host "Position message:" -ForegroundColor green
                    Write-Host $err.InvocationInfo
                    Write-Host $err.InvocationInfo.PositionMessage

                    Write-Host "Script name:" -ForegroundColor green
                    Write-Host $err.InvocationInfo.ScriptName

                    Write-Host "Line:" -ForegroundColor green
                    Write-Host $err.InvocationInfo.LIne

                    Write-Host "..."

                    $ex  = $ex.InnerException
                }
            }

Pretty same outcome, no clue on where the error can be.

With hundreds of functions and scripts, it is a nightmare to figure out what caused the error.

Would you suggest how to handle that with Invoke-Parallel? So that it can be possible to trace the origin of the exception to the actual function or something?

RamblingCookieMonster commented 8 years ago

Hi! I suspect this and #36 are the same - the code that handles this looks at the error stream and writes out any errors that it finds.

There might be a way to work around this, but I haven't run into too many show-stoppers at work (typically triggers for spending more significant amount of time digging in) - Have you tried @proxb's PoshRSJob? Boe writes fantastic code, and that module has become the communities de facto runspace abstraction, so it might be worth seeing if they implement it there.

Totally open to pull requests if you find the cause and prefer to keep using this.

Cheers!

avishnyakov commented 8 years ago

the code that handles this looks at the error stream

Right but the thing is that there are gazillion scripts / functions called underneath. Indeed there is an error but where and how to understand the exact place of the error?

Alright, got the message. Will evaluate PoshRSJob stopping asking anything here.

RamblingCookieMonster commented 8 years ago

Ahh, I gotcha!

So, if there's no way around it, you could take several approaches, for example:

I'm curious, will take a peak at Boe's code, if there's a way around this I'm assuming it will be implemented there, but there's a good chance it will be a bit over my head : )

Cheers!

RamblingCookieMonster commented 8 years ago

Yep, similar issue:

Start-RSJob -ScriptBlock {throw 'wat'} | Wait-RSJob | Receive-RSJob
WriteStream : Exception calling "EndInvoke" with "1" argument(s): "wat"
At C:\Program Files\WindowsPowerShell\Modules\PoshRSJob\1.7.0.0\Public\Receive-RSJob.ps1:102 char:18
+             $_ | WriteStream
+                  ~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,WriteStream

PowerShell is trying to be helpful and gives us details on where the error is emitted - the problem is that we're reading from the error stream, and re-writing the error from these runspace abstraction tools - thus you get context about where the error is seen in the runspace abstraction tool, not your code.

The workarounds I mentioned above (catch and write contextful errors, or log errors to external system) will likely be your best bet.

Cheers!

avishnyakov commented 8 years ago

Sure, might work well. Thanks!