Powershell try/catch rethrow not propagating error (Powershell 2.0)

user459866 picture user459866 · Dec 16, 2010 · Viewed 8.2k times · Source

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.

Answer

Josh picture Josh · Dec 16, 2010

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