In the process of using PowerShell, it was found that the exception handling is not as intuitive as imagined, so here's a summary.
terminating Errors
Errors triggered by Throwterminatingerror are called terminating Errors. Essentially it creates an exception, so we can use catch statements to capture terminating Errors. The other name of terminating Errors is therefore called Exceptions. By default, terminating Errors does not affect the execution of subsequent commands!
Save the following code in the file Exception.ps1:
# The following command does not exist get-terminatingerrorwrite-host ' Hello World '
Then execute the script EXCEPTION.PS1:
Note that the last output of "Hello World", although an error occurred during execution, but the code behind the error is still executed.
The terminating Errors feature is that by default you can capture a catch statement to control the execution flow of the code.
Save the following code in the file Exception.ps1:
try{ # The following command does not exist get-terminatingerror}catch{ Write-Host ' got You ' 1}write-host ' Hello World '
Then execute the script EXCEPTION.PS1:
This is much better, we anticipate the problems that may arise in the code, and decisively end the execution of the script in the event of an error.
Although terminating Errors cannot interrupt execution of the script, it can interrupt execution of the pipeline. As we can see from terminating Errors's documentation, the pipelinestoppedexception exception is thrown inside and PowerShell internally handles the exception. So the execution of the pipeline will be interrupted, and then continue executing the other code later.
non-terminating Errors
Errors triggered by Write-error are called Non-terminating Errors. Essentially it simply writes the error message to the output stream without generating an exception, so the catch statement cannot capture non-terminating Errors by default. By default, non-terminating Errors does not affect the execution of subsequent commands!
Save the following code in the file Exception.ps1:
# C:\xxx does not exist copy-Item C:\xxxWrite-host ' Hello World '
Then execute the script EXCEPTION.PS1:
Note that the last output of "Hello World", although an error occurred during execution, but the code behind the error is still executed.
Non-terminating Errors is characterized by the catch statement cannot capture it by default!
Save the following code in the file Exception.ps1:
try{ # C:\xxx does not exist copy-Item c:\xxx}catch{ Write-Host ' Got You ' 1}write-host ' Hello World '
Then execute the script exception.ps1, the result is the same as above, the code behind the error will still be executed.
Secrets of the ErrorAction option
The non-terminating Errors by default simply writes the error message to the output stream without generating an exception by Write-error, so the catch statement cannot capture Non-terminating Errors. But we can change the default behavior of Writeerror through the-erroraction option.
The erroraction option is primarily used to change the behavior of the non-terminating errors of the command (It will not have an effect on terminating Errors)!
The ErrorAction option works by overriding the $ErrorActionPreference variables of the current command with the specified parameters. By default, the value of the $ErrorActionPreference variable is Continue.
You can specify the following parameters for the-erroraction option:
-erroraction[:{Continue | Ignore | Inquire | Silentlycontinue | Stop | Suspend}]
they represent the following meanings:
Continue Displays the error message and continues with the following command, which is the default value.
Ignore This value was introduced in PowerShell 3.0. It does not display an error message and continues with the following command. Unlike silentlycontinue, it does not add error messages to $Error variables.
Inquire Displays the error message and the frame interacts with the user.
silentlycontinue does not display an error message and continues with the following command.
Stop displays an error message and exits the execution of the script.
Suspend This value applies only to Workflow. Execution pauses when terminating error occurs and then decides whether to resume execution.
Here we focus on the use of more stop, it will let Write-error and other original non-terminating Error command generated terminating error! So we can use catch statements to catch exceptions. Save the following code in the file Exception.ps1:
try{ # C:\xxx does not exist -erroraction Stop}catch{ Write -Host ' got 1}write-host ' Hello World '
Note We added the-erroraction Stop option for the Copy-item command and then executed the script EXCEPTION.PS1:
Haha, this time the catch is abnormal, and finally did not output "Hello World".
It's not fun to add the-erroraction option to each command, but we can set $ErrorActionPreference variables in the script to do the same thing:
$ErrorActionPreference = ' Stop '
In this case, all the original non-terminating error will become terminating error in the current script.
try/catch/finally
finally block is also very important to ensure that some of the necessary logic is executed, such as releasing the database connection. The following demo shows how to set the $ErrorActionPreference variable in a script:
$eap = $ErrorActionPreference try{ $ErrorActionPreference = ' Stop ' # do something Span style= "COLOR: #000000" >}catch{Write -host " error! " Exit 1} Finally { $ErrorActionPreference = $eap }
Restoring $ErrorActionPreference variables in the Finally block ensures that the $ErrorActionPreference variables we set ourselves only affect the statements in the Try/catch block.
$PSItem Variables
$PSItem is a variable of type Errorrecord that holds the details of the exception. When an exception is caught, we can output or save the exception-related information to the log:
$eap $ErrorActionPreference try{ $ErrorActionPreference = ' Stop ' # The following command does not exist get- Terminatingerror} catch{ # More concise information $PSItem. ToString () }Finally{ $ErrorActionPreference$eap }
$PSItem. ToString () has only the wrong description, which will look more concise. Execute the above script:
The information in the red box is provided by the $PSItem. ToString ().
Only error messages do not always help to investigate the root cause of the problem, and it can be a lot better if there is a wrong line number and an exception stack:
$eap $ErrorActionPreference try{ $ErrorActionPreference = ' Stop ' # The following command does not exist get- Terminatingerror} catch{ # contains information about the stack $PSItem}Finally{ $ErrorActionPreference $eap }
This time we directly output the $PSItem, the execution of the above code will get the following output:
This is much better, with the wrong line number and the call stack, you can easily see the cause of the error.
Conclusion
As a scripting language, PowerShell support for exceptions is still very powerful. But features like terminating Errors and non-terminating Errors also bring us a lot of trouble. Hopefully this article will help you better understand the concept of exception-related in PowerShell.
PowerShell Exception Handling