powershelltry-catch

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?


Solution

  • 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 })