PowerShell live documentation

The WriteError function

Catching inside functions

When $ErrorActionPreference is Stop, $PSCmdlet.WriteError exits the current advanced function and throws. However, the exception it throws is not catchable from within the advanced function.

It's worth noting that in PowerShell 2, the exception is caught both inside the function and outside the function. Inside the function we catch a "The pipeline has been stopped." error, and then continue execution within the function. When the function exits, we then throw the original exception.

  1. function TestWriteErrorFunction {
  2.     [CmdletBinding()]
  3.     param()
  4.     $local:ErrorActionPreference = "Stop"
  5.     try {
  6.         $PSCmdlet.WriteError((NewErrorRecord "error in try"))
  7.     } catch {
  8.         Write-Output "caught inside the function: $_"
  9.     }
  10.     Write-Output "after the try-catch"
  11. }
  12. try {
  13.     TestWriteErrorFunction
  14. } catch {
  15.     Write-Output "caught outside the function: $_"
  16. }
Stdout
caught inside the function: The pipeline has been stopped.
after the try-catch
caught outside the function: error in try
caught outside the function: error in try

Write-Error, on the other hand, is catchable inside the function, for both advanced and basic functions.

  1. function TestWriteErrorCmdletAdvanced {
  2.     [CmdletBinding()]
  3.     param()
  4.     $local:ErrorActionPreference = "Stop"
  5.     try {
  6.         Write-Error "error in try"
  7.     } catch {
  8.         Write-Output "caught inside the function: $_"
  9.     }
  10.     Write-Output "after the try-catch"
  11. }
  12. function TestWriteErrorCmdletBasic {
  13.     param()
  14.     $local:ErrorActionPreference = "Stop"
  15.     try {
  16.         Write-Error "error in try"
  17.     } catch {
  18.         Write-Output "caught inside the function: $_"
  19.     }
  20.     Write-Output "after the try-catch"
  21. }
  22. Write-Output "testing advanced function"
  23. try {
  24.     TestWriteErrorCmdletAdvanced
  25. } catch {
  26.     Write-Output "caught outside the function: $_"
  27. }
  28. Write-Output ""
  29. Write-Output "testing basic function"
  30. try {
  31.     TestWriteErrorCmdletBasic
  32. } catch {
  33.     Write-Output "caught outside the function: $_"
  34. }
Stdout
testing advanced function
caught inside the function: error in try
after the try-catch

testing basic function
caught inside the function: error in try
after the try-catch

Setting $?

The WriteError function differs from Write-Error in another way as well. When used inside a function, either advanced or basic, Write-Error will not set $? to false after the function exits. WriteError, on the other hand, will set $? to false after the function exits.

Interestingly, Write-Error will set $? to false within its own scope. WriteError, however, won't touch $? until the function exits.

  1. function AdvancedWriteErrorCmdlet {
  2.     [CmdletBinding()]
  3.     param()
  4.     $local:ErrorActionPreference = "SilentlyContinue"
  5.     Write-Error "an error"
  6.     Write-Output "Inside advanced function calling Write-Error status: $?"
  7. }
  8. function BasicWriteErrorCmdlet {
  9.     param()
  10.     $local:ErrorActionPreference = "SilentlyContinue"
  11.     Write-Error "an error"
  12.     Write-Output "Inside basic function calling Write-Error status: $?"
  13. }
  14. function AdvancedWriteErrorFunction {
  15.     [CmdletBinding()]
  16.     param()
  17.     $local:ErrorActionPreference = "SilentlyContinue"
  18.     $PSCmdlet.WriteError((NewErrorRecord "an error"))
  19.     Write-Output "Inside advanced function calling `$PSCmdlet.WriteError status: $?"
  20. }
  21. AdvancedWriteErrorCmdlet
  22. Write-Output "Advanced function calling Write-Error exited with: $?"
  23. Write-Output ""
  24. BasicWriteErrorCmdlet
  25. Write-Output "Basic function calling Write-Error exited with: $?"
  26. Write-Output ""
  27. AdvancedWriteErrorFunction
  28. Write-Output "Advanced function calling `$PSCmdlet.WriteError exited with: $?"
Stdout
Inside advanced function calling Write-Error status: False
Advanced function calling Write-Error exited with: True

Inside basic function calling Write-Error status: False
Basic function calling Write-Error exited with: True

Inside advanced function calling $PSCmdlet.WriteError status: True
Advanced function calling $PSCmdlet.WriteError exited with: False