Alex Rivera | Logout

Powershell $Error object not immediately populating inside PSM1 module

Asked 2012-07-11T21:49:23.393
10

I'm encountering a peculiar issue with Powershell. I'm catching an Exception in a catch block, but the global $Error object is not being populated.

A trivial example, where this would behave as expected is this:

function Bar
{
  Foo
}

function Foo
{
  try
  {
    $Error.Clear()
    throw "Error!"
  }
  catch
  {
    "Caught an error - current error count $($Error.Count)"  
  } 
  finally
  {
    "Cleaning up - current error count $($Error.Count)"  
  }
}

Output is as you would expect if you call Bar

Caught an error - current error count 1
Cleaning up - current error count 1

The code I'm having trouble with is nearly identical, except that it loads Foo from a module. Not sure if this is a bug, or simply something I don't understand (will have to check my Powershell in Action book!)

If I save Foo off to a module - Foo.psm1

function Foo
{
  try
  {
    $Error.Clear()
    throw "Error!"
  }
  catch
  {
    "Caught an error - current error count $($Error.Count)"  
  } 
  finally
  {
    "Cleaning up - current error count $($Error.Count)"  
  }
}

Export-ModuleMember -Function Foo

Then I perform the following

Import-Module .\Foo.psm1
$Error.Clear()
"Current error count $($Error.Count)"
Foo
"Current error count $($Error.Count)"

I end up with

Current error count 0
Caught an error - current error count 0
Cleaning up - current error count 0
Current error count 1

Notice that Foo no longer sees any changes made to $Error. So the module-ification of the code is changing error propagation behavior. Can anyone chime in with the reasoning behind this?

I should note that I can get at the specific caught exception via the automatic variable $_, but I'm looking to get a hold of the entire collection at this point in the call stack.

Edit
Report

1 Answer

14

As Ethan mentioned, you need to look at $global:error to see all of the errors. Modules always have they're own $error variable but it's (mostly) not used.

background: at one point, we had considered isolating errors that occurred in module code to the module scope but ultimately decided to add all errors to the global error collection since it is essentially a log of errors (like an in-memory eventlog.) Unfortunately the module scoped $error wasn't removed before the release and so you need to use the global scope qualifier to access the "real" $error variable.

Bruce Payette, Microsoft Corporation

answered 2012-07-12T17:48:46.473

Your Answer