PowerShell: detecting errors in script functions

Viewed 31008

What is the best way to detect if an error occurs in a script function? I'm looking for a consistent way to indicate error/success status similar to $? (which only works on cmdlets, not script functions).

Given a particular function might return a value to be used by the caller, we can't indicate success by returning a boolean. A function could use a [ref] parameter and set the value appropriately inside the function and check after the call, but this is more overhead than I'd like. Is there something built-in to PowerShell that we can use?

The best I can come up with is:

  1. In the function use Write-Error to put ErrorRecord objects in the error stream;
  2. call the function with an ErrorVariable parameter;
  3. check if the ErrorVariable parameter is not null after the call.

For example:

function MyFun {
  [CmdletBinding()]    # must be an advanced function or this 
  param ()             # will not work as ErrorVariable will not exist
  process {
    # code here....
    if ($SomeErrorCondition) {
      Write-Error -Message "Error occurred; details..."
      return
    }
    # more code here....
  }
}

# call the function
$Err = $null
MyFun -ErrorVariable Err
# this check would be similar to checking if $? -eq $false
if ($Err -ne $null) {
  "An error was detected"
  # handle error, log/email contents of $Err, etc.
}

Is there something better? Is there a way of using $? in our script functions? I'd rather not throw exceptions or ErrorRecord objects and have tons of try/catch blocks all over the place. I'd also rather not use $Error as would require checking the count before making the function call as there could be other errors in there before the call - and I don't want to Clear() and lose them.

6 Answers

Most of this made a lovely whooshing sound as it went right over my head... ಠ_ಠ

I am with Dan. PS Logging is a complete mess and seems like it will more than double the size of the code I am writing...

Frankly, I would be happy if I could just capture console output directly to logs, warts and all...

The Try/Catch block is so ... so ... crappy, I can smell it and it has made my eyes turn brown.

The $? is very interesting, but you guys actually know what you are doing, as where I am at the point where I have realized I know nothing (last week I thought I knew at least something, but noooooo).

Why the %$#@%$ isn't there something like the 2> in cli ...

Ok so here is what I am trying to do (you've read this far, so why not?):

    Function MyFunc($Param1, $Param2){
Do{
  $Var = Get-Something | Select Name, MachineName, Status 
 $NotherVar = Read-Host -Prompt "Do you want to Stop or Start or check the $Var (1 to Start, 2 to stop, 3 to check, 4 to continue)?" 
    If ($SetState -eq 1) 
     {
      Do Stuff
    }
    ElseIf ($Var -eq 2) 
       {
      Do Stuff
    }
    ElseIf ($Var -eq 3)
       {
      Do Stuff
    }
  }
    Until ($Var -eq 4)
Do other stuff
} 

Did it work? Yes, fine... Log it and continue. No? Then catch the error, log it and continue the script...

I am tempted to just ask for user input, add-content and continue...

Incidentally, I did find a module PSLogging that seems like it would be pretty cool, but I am not sure how to get it working... The documentation is a bit Spartan. Seems like folks are getting it working without too much trouble, so I kinda feel like I am a corner sitting pointy hat kind of person...

Related