Handling errors
Tell terminating from non-terminating errors, catch them with try/catch/finally, and raise your own.
- Explain the difference between non-terminating and terminating errors
- Use -ErrorAction and $ErrorActionPreference to control what happens
- Handle errors with try/catch/finally, typed catches and throw
PowerShell has two kinds of errors:
- Non-terminating errors are reported and then the command carries on. Ask
Get-Itemfor five files when two are missing and you get three files plus two red error messages. - Terminating errors stop the current statement - and the script, unless something catches them.
throw, .NET exceptions (like dividing by zero) and parameter validation failures are terminating.
This matters because try/catch only catches terminating errors. To catch a cmdlet’s non-terminating error, turn it into a terminating one with -ErrorAction Stop - or set $ErrorActionPreference = 'Stop' for the whole script.
1Set-Location ([IO.Path]::GetTempPath())
2try {
3 Get-Item 'no-such-dragon.txt' -ErrorAction SilentlyContinue
4 'still running after a non-terminating error'
5 Get-Item 'no-such-dragon.txt' -ErrorAction Stop
6 'never printed'
7} catch {
8 "caught: $($_.Exception.GetType().Name)"
9}
10try {
11 $meals = 0
12 12 / $meals
13} catch [System.DivideByZeroException] {
14 'caught a division by zero'
15} finally {
16 'finally always runs'
17}still running after a non-terminating error caught: ItemNotFoundException caught a division by zero finally always runs
-ErrorAction value | What happens |
|---|---|
Continue (default) | show the error, carry on |
SilentlyContinue | hide it (it’s still recorded in $Error), carry on |
Ignore | hide it and don’t record it |
Stop | make it terminating, so catch can handle it |
Inquire | ask the user |
Inside catch, $_ is the error record: $_.Exception.Message is the message, $_.Exception the .NET exception, $_.CategoryInfo and $_.InvocationInfo say what failed and where. Put the most specific catch [Type] blocks first and a plain catch last. A finally block runs whether or not anything failed - perfect for closing files and connections.
Raising errors
throw 'message'raises a terminating error. Use it when your function can’t possibly continue.Write-Error 'message'writes a non-terminating error - right when one item of many failed but the rest can go on.- For programs that aren’t PowerShell (git, ping, python...), check
$LASTEXITCODE(their exit code) or$?(did the last command succeed?).
1function Get-Ration {
2 param([int]$Kilograms, [int]$Dragons)
3 if ($Dragons -le 0) { throw "No dragons to feed with $Kilograms kg" }
4 $Kilograms / $Dragons
5}
6foreach ($count in 4, 0, 5) {
7 try {
8 "ration: $(Get-Ration -Kilograms 60 -Dragons $count) kg"
9 } catch {
10 "skipped: $($_.Exception.Message)"
11 }
12}ration: 15 kg skipped: No dragons to feed with 60 kg ration: 12 kg
Try it
Review the night-feed script
A keeper wrote this script to feed the night shift. Click every line that handles errors badly, then check.
Click every part that looks suspicious. There are 4.
Key takeaways
Non-terminating errors report and continue; terminating errors stop the statement.
try/catch only catches terminating errors - add
-ErrorAction Stopto cmdlets inside try.In catch,
$_is the error record;$_.Exception.Messageis its message. finally always runs.throwwhen you can’t continue,Write-Errorwhen one item failed; check$LASTEXITCODEfor native programs.
Lesson quiz
7 questions · pass with 5 correct · up to 50 XP
Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.
Practice: write PowerShell scripts
Write a script in the editor and run it for real against sample input, which is piped into your script as $input. Scripts run on PowerShell 6.2 through Try It Online (tio.run), a free public service, so these exercises avoid PowerShell 7-only syntax; your script and test input are sent there.
Ration planner
Each input line is kilograms dragons. Print the ration per dragon, rounded to one decimal place with [math]::Round(x, 1), like 60 kg / 4 dragons = 15 kg each. If there are no dragons, the division throws - catch it and print 60 kg / 0 dragons = nobody to feed. Use try/catch, not an if.
- Three shifts
Lessons teach PowerShell 7; your script runs on PowerShell 6.2 via Try It Online (tio.run), a free public service, so stick to syntax that works there. Test input is piped into your script as $input. Your script and test input are sent to that service.
Enclosure check
The starter creates notes for some enclosures. Each input line is an enclosure name. For each, read <name>.txt with Get-Content and print volcano: <its contents>; if the file is missing print volcano: MISSING - by catching the error. Finally print checked N, missing M. No red errors may appear.
- Three enclosures
- All missing
Lessons teach PowerShell 7; your script runs on PowerShell 6.2 via Try It Online (tio.run), a free public service, so stick to syntax that works there. Test input is piped into your script as $input. Your script and test input are sent to that service.
Questions about this lesson
Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.
Loading posts…