9

This is a best practice question I suppose.

When designing functions that will be used within scripts, what is the best way to handle errors that could occur within the function?

For example, say we have a basic function that does X and Y:

Function Test-Function
{
    Try
    {
        <# Something in here that would generate an error #>
    }
    Catch
    {
        Throw
    }

    Return $someReturnResultIWantInMyScript
}

My script calls this function:

Try
{
    $ValueIWantFromFunction = Test-Function
}
Catch
{
    <# Do something here #>
}

If the Test-Function hits a terminating error, it will throw to the caller. The Try/Catch around my function call in the script will receive this error and hit its own catch. I can then decide what to do.

If I didn't throw an error within the function, the script wouldn't see the terminating error, and then my $ValueIWantFromFunction could contain $Null or something not useful.

Is this a good way of error handling with functions and function calls within scripts? Is there a better way?

4
  • I am going to say it depends on the use case. For the most part these options exist to give you the choice. Best practice would be to avoid triggering those errors if it can be avoided with other conditional logic. Commented Nov 26, 2017 at 1:07
  • Terminating errors will go up to the caller regardless of your try/catch, unless your try/catch is blocking it. Commented Nov 26, 2017 at 19:34
  • So how do I handle the error if the function is also returning a value (assuming it succeeds?) Commented Nov 26, 2017 at 19:35
  • I have the exact same question as the original question. If I have a long script, then clearly the right move is to make lots of functions. Those functions are "in the weeds" and can give the best information, so try/catch in the function seems to make sense. But then having to try / catch in the script as well, every time I call a function, it gets busy with lots of try/catch. Commented Apr 27, 2021 at 13:14

1 Answer 1

3

As a best practice, I like to use exceptions to handle errors in my functions/scripts and document them so the caller knows what went wrong. For example:

Function Remove-File
{
    [CmdletBinding()]
    [OutputType([Int])]
    Param(
        [Parameter(Mandatory)]
        [String]$Path
    )

    Try
    {
        Remove-Item -Path $Path
        Return 0
    }
    Catch
    {
        Return 1
    }
}

If I'm designing my own function/cmdlet, I'll generate a custom [ErrorRecord] object to be thrown:

#Requires -Version 5
If ($ErrorCondition)
{
    $PSCmdlet.ThrowTerminatingError(
        [System.Management.Automation.ErrorRecord]::new(
            [System.Exception]::new('Error message'),
            'FullyQualifiedName',
            [System.Management.Automation.ErrorCategory]::DeviceError,
            $ErrorCausingObject
        )
    )
}

Using this method, I can include in the documentation which errors get thrown depending on what went wrong so the caller can utilize multiple catches depending on the thrown error and handle it.

Here are some nice articles:
Everything about exceptions
Scripting Guy: Handling errors
On the OutputType attribute

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.