2

I have a try-catch statement within a try-catch statement. The inner catch catches the error, but the throw does not cause the error to be caught in the out catch statement. Breifly, my script is formatted similar to:

$ErrorPreference = "Stop"

try
{
     getStuffFromDB

     putStuffInDB
}
catch
{
     write-host ("Error: " + $error[0])
}

function getStuffFromDB
{
     try
     {
          -- database query statement
     }
     catch
     {
          throw
     }
     finally
     {
          close connection and clean up
     }
}

function putStuffInDB
{
     try
     {
          -- database insert statements statement
     }
     catch
     {
          throw
     }
     finally
     {
          close connection and clean up
     }
}

When I ran the script there were no errors, but I noticed the SQL Server database that I was attempting to populate was missing data. When I re-ran the script in debug, the function 'putStuffInDB' had an error that was caught in the catch block. But when I stepped the message did not get 'thrown' to the outer catch block, but processed the finally block and terminated.

I am obviously missing something that I am not seeing. I have used the construct in C# in the past and never had issues with errors being 'passed' to the outer catch block.

Xavier Poinas
  • 19,377
  • 14
  • 63
  • 95
user459866
  • 121
  • 3
  • 12

3 Answers3

5

I am not seeing that behavior. I ran the following in PowerShell ISE and it produces the expected results. Is it possible that the errors in the database were not in fact thrown as exceptions? I believe in SQL Server for example, certain errors under a given error level are not thrown as exceptions back to the ADO.NET provider.

$ErrorActionPreference = 'Stop'

function Throw1 {
    try {
        Write-Host "Throw1.Try"
        throw "Error from Throw1"
    }
    catch { 
        Write-Host "Throw1.Catch"
        throw
    }
    finally {
        Write-Host "Throw1.Finally"
    }
}

function Throw2 {
    try {
        Write-Host "Throw2.Try"
        throw "Error from Throw2"
    }
    catch {
        Write-Host "Throw2.Catch"
        throw
    }
    finally {
        Write-Host "Throw2.Finally"
    }
}

function Test {
    try {
        Throw1
        Throw2
    }
    catch {
        Write-Host $error[0]
    }
}

Test

Produces the following:

Throw1.Try
Throw1.Catch
Throw1.Finally
Error from Throw1
Josh
  • 68,005
  • 14
  • 144
  • 156
  • Your comment about SQL Server severity level may have something to do with this, though it is not clear at this point. But, the inner catch block does catch the error and rethrows it. It is the out catch block that does not catch the error. As a test, in my insert statement I misspelled a column name which should generate a high enough severity level but still does not get caught in the outer catch. – user459866 Dec 17 '10 at 00:09
  • Did you run my script? On my machine, it executes in the expected order. I'm not sure what else could be different in your case. – Josh Dec 17 '10 at 05:02
1

The variable you want to set is $ErrorActionPreference, not $ErrorPreference.

(Josh did set the right variable.)

OldFart
  • 2,411
  • 15
  • 20
  • I made that correction but it did not help. Though I would not think so, I have a main app in one ps1 file and the database interfaces are in separate script files. My understanding is the $ErrrrorActionPreference specification should apply to all scripts that are called by the main app.so as far as I understand it, this structure should not alter the action of the try/catch. – user459866 Dec 16 '10 at 18:40
1

I realized that the problem was of my own doing. In the POSH functions to create the SQLServer entries I returned the primary key of the data set created. The design of the functions was such that the function would return the primary key. The design mistake was that I put a return statement in the finally block which superceded the throw back to the outer catch. I have changed the design removing the return statement. The try/catch now works correctly.

user459866
  • 121
  • 3
  • 12