PowerShell Try, Catch, custom terminating error message

11,223

Something like this, maybe?

Try {
      $File = (Import-Csv -Path c:\test.csv)

      if(!(Test-Path $LogFolder -PathType Container)) 
      { throw "Can't find the log folder: '$LogFolder'" }

      $Credentials = Import-Credentials $UserName $PasswordFile

      }

catch {
        Switch -Wildcard ($Error[0].CategoryInfo)
        {
           '*[Import-CSV]*' 
           { $FailType = 'Import CSV failed' }

           '*[Test-Path]*'
           { $FailType = 'LogFolder not found' }

           '*[Import-Credentials]*'
           { $FailType = 'Credential import failed' }

           Default
           { $FailType = 'Unrecognized error' }

         }

         $Error[0].Exception.Message | Send-Mail $ScriptAdmin $FailType

       }

Edit (for some reason I'm not able to post a comment):

I should have specified that it wasn't tested, and was intended more as a pattern than a finished solution, and it seems to have done what it was intended to do.

@BartekB - I habitually use $Error[0] instead of $_ because it seems more explicit and intuitive to read, and less likely to be misunderstood by someone less experienced who might inherit the code later.

Share:
11,223
DarkLite1
Author by

DarkLite1

Master Bruce... why do we fall? So we can learn to stand up again.

Updated on June 14, 2022

Comments

  • DarkLite1
    DarkLite1 almost 2 years

    Is there a way to customize the error message of a terminating error?

    In the example below I would like to just end up with one Try section and collect all errors in one Catch section by combining both script blocks. My problem is that the $error generated by Import-csv is not descriptive enough and I would like to have the text Failed CSV-File import c:\test.csv within the $error message.

    Thank you for your advise.

    Script block 1

    Try {
        $File = (Import-Csv -Path c:\test.csv)
    }
    Catch {
        throw $error[0].Exception.Message | Send-Mail $ScriptAdmin "FAILED CSV-File import"
    }
    

    Script block 2

    try {
        if(!(Test-Path $LogFolder -PathType Container)) {throw "Can't find the log folder: '$LogFolder'"}
        $Credentials = Import-Credentials $UserName $PasswordFile
    }
    catch {
        throw $Error[0].Exception.Message | Send-Mail $ScriptAdmin "FAILURE"
    }
    

    Workaround

    A possible solution would be to check first with test-path if the import file exists and then create a throw with a customized message. But I would like to know if it's possible to handle it in one line of code without using test-path first.

    Best solution (thanks to mjolinor):

    try {
        $File = (Import-Csv -Path $ImportFile -Header "A", "B", "C", "D" | Where { $_.A -NotLike "#*" })
        if(!(Test-Path $LogFolder -PathType Container)) {throw "Can't find the log folder: '$LogFolder'"}
        $Credentials = Import-Credentials $UserName $PasswordFile
    }
    catch {
        Switch -Wildcard ($Error[0].Exception)
            {
               "*$ImportFile*"
               { $FailType = "FAILED CSV-File import" }
    
               "*$LogFolder*"
               { $FailType = "FAILED Log folder not found" }
    
               "*Import-Credentials*"
               { $FailType = "FAILED Credential import" }
    
               Default
               { $FailType = "FAILED Unrecognized error" }
    
             }
           Write-Warning $Error[0].Exception.Message
           throw $Error[0].Exception.Message | Send-Mail $ScriptAdmin $FailType
    }
    
    • Make sure that your advanced-function which you created (like Import-Credentials above) contains the function name in the throw section. So we can filter it out in the catchblock.
  • DarkLite1
    DarkLite1 almost 10 years
    Thank you mjolinor, that's exactly what I'm looking for. However, it errors out with The specified wildcard character pattern is not valid: *[Import-CSV]* although $error[0] contains the matching word: + CategoryInfo : OpenError: (:) [Import-Csv], FileNotFoundException`
  • DarkLite1
    DarkLite1 almost 10 years
    Works like a charm when removing the brackets [], from '*[Import-CSV]*' to '*Import-CSV*'. Thanks again, this helped me a lot :)
  • DarkLite1
    DarkLite1 almost 10 years
    For Test-Path this doesn't work, because the field $Error[0].CategoryInfodoesn't contain the word Test-Path as it's not in the throw. Is there a way to set the CategoryInfo from within throw?
  • DarkLite1
    DarkLite1 almost 10 years
    Found it, the best way to do it (thanks to your help) is using $Error[0].Exception and then put the variables used as wildcards, like *$ImportFile* and *$LogFolder* and others. I'll mark your answer as Solved. Thanks again :) I'll update the post with the full solution to for others.
  • BartekB
    BartekB almost 10 years
    BTW: any reason why you use $Error[0] instead of $_? Latter (by definition) should contain thrown error.