Home > Blockchain >  Is it possible to create a function only for a catch block?
Is it possible to create a function only for a catch block?

Time:03-15

I have multiple try catch blocks and all of them are using the same catch block.

    try {   
        invoke-command -cn $host -Credential $cred -ScriptBlock {
        param($name)    
        statement...
        } -ArgumentList $name
        
    } catch {
        $formatstring = "{0} : {1}`n{2}`n"  
                    "      CategoryInfo          : {3}`n"  
                    "      FullyQualifiedErrorId : {4}`n"
        write-host ($formatstring)
        exit 1
    }

...

    try {   
    another statement...
        
    } catch {
        $formatstring = "{0} : {1}`n{2}`n"  
                    "      CategoryInfo          : {3}`n"  
                    "      FullyQualifiedErrorId : {4}`n"
        write-host ($formatstring)
        exit 1
    }

I want to ask if it is possible to create a function which has the catch block so that I can call and use the function instead of writing the same catch block multiple times.

I am using poweshell 5

CodePudding user response:

catch requires a literal { ... } block to follow it, but from inside that block you're free to call reusable code, such as a function, or, in the simplest case, a script block:

# Define a script block to use in multiple `catch` blocks.
$sb = {
  "[$_]" # echo the error message
}

# Two simple sample try / catch statements:

try {
  1 / 0
}
catch {
  . $sb # `. <script-block>` invokes the block directly in the current scope
}

try {
  Get-Item -NoSuchParam
}
catch {
  . $sb
}

Note: ., the dot-sourcing operator, is used to invoke the script block directly in the current scope, allowing you to directly modify that scope's variables.
If, by contrast, you want to execute the script block in a child scope, use &, the call operator.

CodePudding user response:

You can create a ScriptBlock which can be called using the Invocation (call - &) Operator.

$callMe = {
    $formatstring = "{0} : {1}`n{2}`n"  
    "      CategoryInfo          : {3}`n"  
    "      FullyQualifiedErrorId : {4}`n"
    Write-Host -Object $formatstring
    exit 1
}

try {   
    Invoke-Command -ComputerName $host -Credential $cred -ScriptBlock {
        param($name)    
            # statement...
    } -ArgumentList $name -ErrorAction "Stop"
} 
catch {
    & $callMe
}

As a side note, if you ever find yourself repeating code, there is probably something you can do about that. I would suggest either setting $ErrorActionPreference to stop, or add a -ErrorAction "Stop" to your Invoke-Command to ensure a terminating error is thrown.

  • Best practice is to set $ErrorActionPreference back to "Continue" if used.
  • I also believe you're looking to use the -f (format) operator.
  • Related