This post is part of the Second Wednesday Demo Session, Click here for more info about additional demo posts.
In order to catch and handle errors in PowerShell we can use the Trap keyword. Trap has the following Syntax:
trap [[error type]] {statement list}
If we try to merge a value of the type System.Int32 with a value of type System.String an error occurs.
PS > [int]1 + [string]"Hello"
Cannot convert value "Hello" to type "System.Int32". Error: "Input string was not in
a correct format."
At line:1 char:9
+ [int]1 + <<<< [string]"Hello"
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
We can get the type of error that occured by checking the InnerException.
PS > $Error[0].Exception.InnerException.GetType().FullName
System.Management.Automation.PSInvalidCastException
With this information, we can handle the errors of the type System.Management.Automation.PSInvalidCastException using a simple trap. In the example below
we create a funtion that shows how to handle these types of errors.
function TrapError([scriptblock]$Command) {
Trap [System.Management.Automation.PSInvalidCastException] {
Write-Host "My Custom Error Message" -ForegroundColor Red
Continue
}
& $Command
}
When we call the function our custom error message is returned instead of the default error message.
PS > TrapError -Command { [int]1 + [string]"Hello" }
My Custom Error Message
But what if we generate another kind of error. Let's try to divide 1 by $null.
PS > TrapError -Command { 1/$null }
Attempted to divide by zero.
At line:1 char:24
+ TrapError -Command { 1/ <<<< $null }
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : RuntimeException
This time the error was not handled since it's a different type of error. We can of course modify our function to handle these types of errors as well.
function TrapError([scriptblock]$Command) {
Trap [System.Management.Automation.PSInvalidCastException] {
Write-Host "My Custom Error Message" -ForegroundColor Red
Continue
}
Trap [System.DivideByZeroException] {
Write-Host "1/`$null doesn't really work.." -ForegroundColor Red
Continue
}
& $Command
}
If we try the same command again, the error is handled.
PS > TrapError -Command { 1/$null }
1/$null doesn't really work..
We can also add a Trap keyword without a specific error type to handle other types of errors that may occur.
function TrapError([scriptblock]$Command) {
Trap [System.Management.Automation.PSInvalidCastException] {
Write-Host "My Custom Error Message" -ForegroundColor Red
Continue
}
Trap [System.DivideByZeroException] {
Write-Host "1/`$null doesn't really work.." -ForegroundColor Red
Continue
}
Trap {
Write-Host "This really doesn't work.." -ForegroundColor Red
Continue
}
& $Command
}
If we try to create an instance of a .NET Object and specify a nonexisting class, the error is handled by the trap.
PS > TrapError -Command { New-Object System.Blah }
This really doesn't work..
Some Errors are handled in other ways in commands and scripts. a typical example is the Get-ChildItem cmdlet.
If we use our function and use Get-ChildItem and try to retrieve a folder that doesn't exist, the cmdlet will handle
the error.
PS > TrapError -Command { Get-ChildItem C:\Blah }
Get-ChildItem : Cannot find path 'C:\Blah' because it does not exist.
At line:1 char:35
+ TrapError -Command { Get-ChildItem <<<< C:\Blah }
+ CategoryInfo : ObjectNotFound: (C:\Blah:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
We can override this and manage the error in our trap by setting the ErrorAction parameter to Stop.
PS > TrapError -Command { Get-ChildItem C:\Blah -ErrorAction Stop }
This really doesn't work..