tsunami

log in
history

PowerShell: error handling

Luke Breuer
2010-04-17 04:30 UTC

Philosophy of PowerShell error handling
Note: this is just a guess. Because Microsoft did not seem to think it was important to document error handling, guesses are all we have at the moment. See what they said:
We pride ourselves about being a bit overboard when it comes to Error handling. That is why our sparse (non-existing?) documentation of THROW and TRAP handling is both ironic and sad. 10,000 apologizes for that, we'll fix it in the next release.

The default $ErrorActionPreference is Continue, which means that exceptions thrown are reported, but execution continues to the next command (commands are terminated by newline or ;). This makes sense from a historical shell perspective — users of traditional shells are used to checking return codes and optionally terminating, instead of having a command failure terminate script execution.
try...catch...finally
Available in version 2.0
PowerShell Team Blog
Documenting trap and throw
Managing non-terminating errors
-ErrorAction and -ErrorVariable
$errorview = 'categoryview'
-ErrorAction SilentlyContinue => -EA 0
Strict Mode V1 Debug Tool V1 / V2 Best Practice

Part 1 Teminating vs. Non-Terminating, ErrorRecord
Part 2 $error
Part 3 Write-Host
Part 4 Set-MshDebug (now Set-PSDebug)
Part 5 Preferences and Commandline Options
Part 6 Trace-Expression, Breakpoint Script (perhaps it is now Trace-Command?)
Part 7 How Traps Work
Other
Trap Exception { “In PowerShell” }
Undocumented facts
If a trap block does not have return, break, or continue, return is implied.
Code snippets
continue returns to trap scope
#trap_scope.ps1
trap
{
    'in trap{}'
    continue
}

if ($true)
{
    'first statement in if block'
    throw 'oh noes'
    'last statement in if block'  # never executed
}
'end of script'
executing:
# .\trap_scope.ps1
first statement in if block
in trap{}
end of script

From the PowerShell blog:
You may ask, why is this? Remember that trap statements operate in the scope in which they are declared. We had implementation and performance problems in exiting the "function a" scope, running the trap block in the outer scope, then returning to the "function a" scope.
return utilizes $ErrorActionPreference
#trap_ea.ps1
param($ea_pref)

$ErrorActionPreference = $ea_pref
trap
{
    'in trap{}'
    return
}

'begin script'
throw 'oh noes'
'end script'
executing with $ErrorActionPreference = Stop, Continue, SilentlyContinue:
# .\trap_ea.ps1 Stop
begin script
in trap{}
oh noes
At C:\ps\ex\trap_ea.ps1:12 char:6
+ throw  <<<< 'oh noes'

# .\trap_ea.ps1 Continue
begin script
in trap{}
oh noes
At C:\ps\ex\trap_ea.ps1:12 char:6
+ throw  <<<< 'oh noes'
end script

# .\trap_ea.ps1 SilentlyContinue
begin script
in trap{}
end script