June 3, 2009

Powershell Exception Helper

Powershell does not really have a good way to log and handle exceptions. You can find a bunch of articles on the Trap keyword and what can be done with it. Here is one great article on the topic. Having said that, my co-worker 'AC' did it again and created this wonderful helper file which I figured I would share with you. You can use this code inside every function at the first line. This works very well if you have many posh scripts being called:
function MyFunction($param1, $param2)
{
trap { TrackError }
....
}

$global:trackedErrorHashCode = $null

function TrackError
{
$err = $error[0]
$hashCode = $err.GetHashCode()

if($global:trackedErrorHashCode -eq $hashCode) {
return
}
else {
$global:trackedErrorHashCode = $hashCode
}

$text = BuildErrorMessage $err
WriteErrorMessage $text
SaveErrorMessage $text

throw $err
}

function BuildErrorMessage($err)
{
$text = ""
$text += FormatAsLine "Error ----------------------"
$text += FormatAsLine
$text += FormatAsLine "$($err.InvocationInfo.InvocationName): $($err)"
$text += FormatAsLine $err.InvocationInfo.PositionMessage
$text += FormatAsLine
$text += FormatAsLine "$($err.Exception.GetType().Name)"
$text += FormatAsLine

$text += FormatAsLine "StackTrace -----------------"
$text += FormatAsLine
$info = $err.InvocationInfo
$stack = Get-PSCallStack

$text += FormatCallStackLine $stack[2].command $info.ScriptName $info.ScriptLineNumber

$stack[3..$stack.length] | % {
$text += FormatCallStackLine $_.Command $_.ScriptName $_.ScriptLineNumber
}
$text += FormatAsLine "----------------------------"

$text
}

function FormatAsLine($text)
{
$text + "`n"
}

function FormatCallStackLine($command, $file, $lineNumber)
{
" At '$command' in $($file):$lineNumber`n"
}

function WriteErrorMessage($text)
{
Write-Host $text -fore green
}

$global:_savedErrorMessages = @()

function SaveErrorMessage($text)
{
$global:_savedErrorMessages += $text
}

function GetErrorMessages()
{
$global:_savedErrorMessages
}

No comments:

Post a Comment