pteranodon
pteranodon

Reputation: 2059

Powershell - Catch [System.???] - How do I find the ??? to use?

On a particularly deep directory, the code: $files = Get-ChildItem -Path $d.FullName -File -Recurse -ErrorAction SilentlyContinue is resulting in

Get-Childitem : The script failed due to call depth overflow.
At K:\proj000\QC\sully\FindLatestTryCatch_format.ps1:8 char:10
+ $files = Get-Childitem -Path $d.Fullname -File -Recurse -ErrorAction  ...
+          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (0:Int32) [Get-ChildItem], ScriptCallDepthException
    + FullyQualifiedErrorId : CallDepthOverflow,Microsoft.PowerShell.Commands.GetChildItemCommand

I would like to wrap my GCI call in a try-catch block, but I have no idea what to specify in the catch [???] {} inside the square brackets. Can I pull text out of the Error Message shown? Some property of $Error?

Upvotes: 1

Views: 54

Answers (1)

Santiago Squarzon
Santiago Squarzon

Reputation: 60838

If you look at your error, in CategoryInfo you can see the exception type being thrown:

InvalidOperation: (0:Int32) [Get-ChildItem], ScriptCallDepthException

So basically:

[System.Management.Automation.ScriptCallDepthException]::new()

And if you wanted to catch that specific exception type then you could do:

try {
    $files = Get-ChildItem -Path $d.FullName -File -Recurse -ErrorAction SilentlyContinue
}
catch [System.Management.Automation.ScriptCallDepthException] {
    # handle call depth exception
}

However do note it isn't mandatory to always specify an exception type to catch, you could simply catch any exception (this essentially means, catch all types inheriting Exception):

try {
    $files = Get-ChildItem -Path $d.FullName -File -Recurse -ErrorAction SilentlyContinue
}
catch {
    # handle any exception
}

Also consider that you are able to catch this exception because the cmdlet is either using ThrowTerminatingError or it wasn't handled by the cmdlet. This also explains why -ErrorAction SilentlyContinue didn't have any effect.

For non-terminating errors, you would only be able to catch them if your error preference was Stop.


Aside from the question, the error is likely due to the recursion used in the cmdlet, try using .NET directly if you have PowerShell 7 this will likely work properly and be much faster:

$files = $d.GetFiles('*', [System.IO.EnumerationOptions]@{ RecurseSubdirectories = $true })

Upvotes: 1

Related Questions