ASP.NET Weblogs

Welcome to ASP.NET Weblogs Sign in | Join | Help
in Search

The Technical Adventures of Adam Weigert

PowerShell: Try...Catch...Finally Comes To Life

So, PowerShell has some good error handling, but being so used to .NET, I really missed my Try...Catch...Finally statements. Especially when I needed to make sure a block of code always executed. Well, after some playing, I think I have the solution! I've tested this function in a few different ways. I hope this turns out to be as helpful to someone else as it is for me. Maybe Microsoft will add this functionality to the core of PowerShell.

function Try
{
    param
    (
        [ScriptBlock]$Command = $(throw "The parameter -Command is required."),
        [ScriptBlock]$Catch   = { throw $_ },
        [ScriptBlock]$Finally = {}
    )
   
    & {
        $local:ErrorActionPreference = "SilentlyContinue"
       
        trap
        {
            trap
            {
                & {
                    trap { throw $_ }
                    &$Finally
                }
               
                throw $_
            }
           
            $_ | & { &$Catch }
        }
       
        &$Command
    }

    & {
        trap { throw $_ }
        &$Finally
    }
}

# Example usage 

Try {
    echo " ::Do some work..."
    echo " ::Try divide by zero: $(0/0)"
} -Catch {
    echo "  ::Cannot handle the error (will rethrow): $_"
    #throw $_
} -Finally {
    echo " ::Cleanup resources..."
}

Published Oct 10 2007, 05:18 PM by adweigert
Filed under: ,

Comments

 

Cash Foley said:

Great stuff.  I can't figure out what the 'local' on ErrorActionPreference actually accomplishes.  Is the behavior actually different if you leave it off?

October 13, 2007 1:29 AM
 

adweigert said:

No, it isn't needed, I was just being explicit to show that this is only valid for the current scope.

It is just my personal standard when overriding a possible non-local variable.

October 13, 2007 10:24 AM
 

Helge Klein said:

This looks great! I have been looking for this functionality for a long time.

Thanks for sharing this.

October 17, 2007 7:48 AM
 

Matt said:

Thanks for the function. I'm really excited to try this out. I've been playing around with this for the past 30 mins and am scratching my head more than I expected.

Could you by chance add additional example of calling the function (particularly examples of real-world catch blocks)? I think seeing more working examples would be very helpful.

Thanks again!

November 5, 2007 6:04 PM