Terminating & Non-Terminating error behavior

I am trying to manage error handling in a script, that uses a self made module.

What I would like to have is an error that would not end the script, AND that would get caught in in try/catch statement.

Seems easy, and hundreds of commands work like this.
example :

  • invoke-restmethod does not end a script when failing
  • you can surround invoke-restmethod with a try/catch. It works.

Let’s have 2 very simple files for our test

Test.ps1m

function send-Terror {     throw "Terminating error" }
Export-ModuleMember -Function send-terror

function send-NTerror { Write-error "Non-Terminating error" }
Export-ModuleMember -Function send-NTerror

test.ps1

Import-Module .\Test.psm1 -force
$error.Clear()

Write-host "NON-TERMINATING"
try { send-NTerror } catch { write-host "NT 1/2 : success" -foregroundcolor green }
send-NTerror
write-host "NT 2/2 : success" -foregroundcolor green

Write-host "TERMINATING"
try { send-Terror } catch { write-host "T 1/2 : success" -foregroundcolor green }
send-Terror
write-host "T 2/2 : success, script ended" -foregroundcolor green

This simple script will (besides on screen error) write :

NON-TERMINATING
NT 2/2 : success
TERMINATING
T 1/2 : success

As you can see, and as explained, it is not possible to grab a non terminating error within a try catch
But, throwing a terminating error will end the script.
I would like to avoid, each time I am using those commands, to add either :

  • Surrounding try/catch statements
  • Adding -ErrorAction SilentlyContinue

I would like to be able to send a terminating error that does not end the script, using a self made module.

Any advices welcome

Hi, welcome to the forum :wave:

A terminating error won’t end the script when caught, but you have send-Terror both inside and outside of your try{} block (although you’ve misspelt it in the try{} block). The send-Terror that’s not in the try{} block won’t be caught and will terminate the script.

function test {
    throw 'Whoops!'
}

try {
    test
}
catch {
    Write-Warning 'Something went wrong with test.'
}

Write-Output "Now I'm going to sleep."
Start-Sleep -Seconds 10
Write-Output "Now I'm awake again."

Yes, but my question is how do I write function with a terminating error that

  • Will not stop my script without try/catch statement (or using -erroraction)
  • AND that can still be caught within a try/catch if desired

As the example I have highlighted, within a script, this line will NOT terminate a script
invoke-restmethod https://fake.url
But, if desired, it can be caught in a Try/Catch
try {invoke-restmethod https://fake.url} catch { "Yes ! This code is ran" }

Another way to resolve this, would be to be able to determine if my last command did raise a non terminating error.
Of course, I could do a $error.count before / after to see if the number of $errors grew, but I would like my scripts to stay as clean as possible. This code is meant to be ran in a very large number of scripts.

Thank you for both your welcome and for answering me

OK, understood.

The difference here is that there are two types of terminating errors: statement-terminating which is what you see with Invoke-RestMethod and script-terminating which is what throw generates.

If you want your function to generate a statement-terminating error, you can use $PSCmdlet.ThrowTerminatingError().
That won’t stop the script, but it will be caught in a try/catch block.

1 Like

:sparkling_heart:
Thanks