11---
22description : Error handling is just part of life when it comes to writing code.
33ms.custom : contributor-KevinMarquette
4- ms.date : 03/29 /2026
4+ ms.date : 04/02 /2026
55title : Everything you wanted to know about exceptions
66---
77# Everything you wanted to know about exceptions
@@ -12,9 +12,9 @@ can easily handle exceptions generated by other people's code or you can generat
1212exceptions for others to handle.
1313
1414> [ !NOTE]
15- > The [ original version] [ 07 ] of this article appeared on the blog written by [ @KevinMarquette ] [ 08 ] .
15+ > The [ original version] [ 08 ] of this article appeared on the blog written by [ @KevinMarquette ] [ 09 ] .
1616> The PowerShell team thanks Kevin for sharing this content with us. Please check out his blog at
17- > [ PowerShellExplained.com] [ 05 ] .
17+ > [ PowerShellExplained.com] [ 06 ] .
1818
1919## Basic terminology
2020
4444
4545### Terminating and non-terminating errors
4646
47- PowerShell has three categories of errors. A _ non-terminating error_ (generated
48- by ` Write-Error ` ) adds an error to the error stream without stopping execution
49- and does not trigger ` catch ` . A _ statement-terminating error_ (generated by
50- ` $PSCmdlet.ThrowTerminatingError() ` , engine errors, or .NET method exceptions)
51- stops the current statement but allows the script to continue at the next
52- statement. A _ script-terminating error_ (generated by ` throw ` , parse errors, or
53- ` -ErrorAction Stop ` escalation) unwinds the entire call stack. Both
54- statement-terminating and script-terminating errors can be caught by
55- ` try/catch ` . For a comprehensive reference, see
56- [ about_Error_Handling] ( /powershell/module/microsoft.powershell.core/about/about_error_handling ) .
47+ PowerShell has three categories of errors.
48+
49+ - A _ non-terminating error_ adds an error to the error stream without stopping execution and doesn't
50+ trigger ` catch ` . By default, ` Write-Error ` generates non-terminating errors.
51+ - A _ statement-terminating error_ stops the current statement but allows the script to continue at
52+ the next statement. Statement-terminating errors can be generated by engine errors,
53+ ` $PSCmdlet.ThrowTerminatingError() ` , or .NET method exceptions.
54+ - A _ script-terminating error_ unwinds the entire call stack. Script-terminating errors can be
55+ generated by ` throw ` , parse errors, or ` -ErrorAction Stop ` escalation.
56+
57+ Both statement-terminating and script-terminating errors can be caught by ` try/catch ` . For a
58+ comprehensive reference, see [ about_Error_Handling] [ 04 ] .
5759
5860### Swallowing an exception
5961
@@ -111,7 +113,7 @@ Start-Something -ErrorAction Stop
111113```
112114
113115For more information about the ** ErrorAction** parameter, see [ about_CommonParameters] [ 03 ] . For more
114- information about the ` $ErrorActionPreference ` variable, see [ about_Preference_Variables] [ 04 ] .
116+ information about the ` $ErrorActionPreference ` variable, see [ about_Preference_Variables] [ 05 ] .
115117
116118### Try/Catch
117119
@@ -430,7 +432,7 @@ catch [System.IO.FileNotFoundException]
430432I compiled a master list with the help of the Reddit ` r/PowerShell ` community that contains hundreds
431433of .NET exceptions to complement this post.
432434
433- - [ The big list of .NET exceptions] [ 06 ]
435+ - [ The big list of .NET exceptions] [ 07 ]
434436
435437I start by searching that list for exceptions that feel like they would be a good fit for my
436438situation. You should try to use exceptions in the base ` System ` namespace.
@@ -562,57 +564,50 @@ the users of your Cmdlet.
562564
563565## How try/catch changes error propagation
564566
565- Inside a ` try ` block, PowerShell sets an internal flag that causes all
566- statement-terminating errors to propagate to the ` catch ` block. This is by
567- design, not a corner case. The following example demonstrates this behavior.
568-
569- Outside ` try/catch ` , a statement-terminating error from a child scope does not
570- stop the parent scope. Here is a function that generates a divide by zero
571- runtime exception.
567+ Inside a ` try ` block, PowerShell sets an internal flag that causes all statement-terminating errors
568+ to propagate to the ` catch ` block. This is by design, not a corner case. The following example
569+ demonstrates this behavior.
572570
573571``` powershell
574572function Start-Something { 1/(1-1) }
575573```
576574
575+ Outside ` try/catch ` , a statement-terminating error from a child scope doesn't stop the parent scope.
576+ Here is a function that generates a divide by zero runtime exception.
577+
577578Invoke it like this to see the error reported while the script continues.
578579
579580``` powershell
580581&{ Start-Something; Write-Output "We did it. Send Email" }
581582```
582583
583- But placing that same code inside a ` try/catch ` , the error propagates to the
584- ` catch ` block.
584+ But placing that same code inside a ` try/catch ` , the error propagates to the ` catch ` block.
585585
586586``` powershell
587- try
588- {
587+ try {
589588 &{ Start-Something; Write-Output "We did it. Send Email" }
590- }
591- catch
592- {
589+ } catch {
593590 Write-Output "Notify Admin to fix error and send email"
594591}
595592```
596593
597- The error is caught and the subsequent ` Write-Output ` inside the script block
598- does not run. This is standard ` try/catch ` behavior — all terminating errors
599- within the ` try ` block are caught, whether they originate in the current scope
600- or in a child scope.
594+ The error is caught and the subsequent ` Write-Output ` inside the script block doesn't run. This is
595+ standard ` try/catch ` behavior — all terminating errors within the ` try ` block are caught, whether
596+ they originate in the current scope or in a child scope.
601597
602598### $PSCmdlet.ThrowTerminatingError() inside try/catch
603599
604- ` $PSCmdlet.ThrowTerminatingError() ` creates a statement-terminating error
605- within the cmdlet. After the error leaves the cmdlet, the caller treats it as a
606- non-terminating error by default. The caller can escalate it back to a
607- terminating error by using ` -ErrorAction Stop ` or calling it from within a
608- ` try{...}catch{...} ` .
600+ ` $PSCmdlet.ThrowTerminatingError() ` creates a statement-terminating error within the cmdlet. After
601+ the error leaves the cmdlet, the caller treats it as a non-terminating error by default. The caller
602+ can escalate it back to a terminating error by using ` -ErrorAction Stop ` or calling it from within a
603+ ` try/catch ` block.
609604
610605### Public function templates
611606
612- One last takeaway I had with my conversation with Kirk Munro was that he places a
613- ` try{...}catch{...} ` around every ` begin ` , ` process ` and ` end ` block in all of his advanced
614- functions. In those generic catch blocks, he has a single line using
615- ` $PSCmdlet.ThrowTerminatingError($PSItem) ` to deal with all exceptions leaving his functions.
607+ One last takeaway I had with my conversation with Kirk Munro was that he places a ` try/catch ` block
608+ inside every ` begin ` , ` process ` and ` end ` block in all his advanced functions. In those generic
609+ catch blocks, he has a single line using ` $PSCmdlet.ThrowTerminatingError($PSItem) ` to deal with all
610+ exceptions leaving his functions.
616611
617612``` powershell
618613function Start-Something
@@ -622,12 +617,9 @@ function Start-Something
622617
623618 process
624619 {
625- try
626- {
620+ try {
627621 ...
628- }
629- catch
630- {
622+ } catch {
631623 $PSCmdlet.ThrowTerminatingError($PSItem)
632624 }
633625 }
@@ -677,8 +669,9 @@ advice and make `ThrowTerminatingError` my goto exception handler for every func
677669[ 01 ] : /dotnet/api
678670[ 02 ] : /dotnet/api/System.IO.FileNotFoundException
679671[ 03 ] : /powershell/module/microsoft.powershell.core/about/about_commonparameters
680- [ 04 ] : /powershell/module/microsoft.powershell.core/about/about_preference_variables
681- [ 05 ] : https://powershellexplained.com/
682- [ 06 ] : https://powershellexplained.com/2017-04-07-all-dotnet-exception-list
683- [ 07 ] : https://powershellexplained.com/2017-04-10-Powershell-exceptions-everything-you-ever-wanted-to-know/
684- [ 08 ] : https://twitter.com/KevinMarquette
672+ [ 04 ] : /powershell/module/microsoft.powershell.core/about/about_error_handling
673+ [ 05 ] : /powershell/module/microsoft.powershell.core/about/about_preference_variables
674+ [ 06 ] : https://powershellexplained.com/
675+ [ 07 ] : https://powershellexplained.com/2017-04-07-all-dotnet-exception-list
676+ [ 08 ] : https://powershellexplained.com/2017-04-10-Powershell-exceptions-everything-you-ever-wanted-to-know/
677+ [ 09 ] : https://twitter.com/KevinMarquette
0 commit comments