2010-12-16 16 views
1

Ich habe eine try-catch-Anweisung innerhalb einer try-catch-Anweisung. Der innere Fang fängt den Fehler ab, aber der Wurf führt nicht dazu, dass der Fehler in der Out-Catch-Anweisung gefangen wird. Breifly, mein Skript ist so formatiert, ähnlich wie:Powershell try/catch retrow nicht propagierenden Fehler (Powershell 2.0)

$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 
    } 
} 

Als ich das Drehbuch lief es keine Fehler aufgetreten sind, aber ich merkte, die SQL Server-Datenbank, die ich versucht wurde zu füllen wurde fehlenden Daten. Wenn ich das Skript in debug erneut ausgeführt habe, hatte die Funktion 'putStuffInDB' einen Fehler, der im catch-Block abgefangen wurde. Aber als ich trat, wurde die Nachricht nicht zum äußeren Catch-Block "geworfen", sondern der finally-Block verarbeitet und beendet.

Ich vermisse offensichtlich etwas, das ich nicht sehe. Ich habe das Konstrukt in C# in der Vergangenheit verwendet und hatte nie Probleme mit Fehlern, die an den äußeren Catch-Block "weitergegeben" wurden.

Antwort

1

ich, dass das Problem meiner eigenen Tuns war realisiert. In den POSH-Funktionen zum Erstellen der SQLServer-Einträge habe ich den Primärschlüssel des erstellten Datensatzes zurückgegeben. Der Entwurf der Funktionen war derart, dass die Funktion den Primärschlüssel zurückgeben würde. Der Konstruktionsfehler war, dass ich eine Rückmeldung in den finally Block geschrieben habe, die den Wurf zurück zum äußeren Fangen übertrug. Ich habe den Entwurf geändert, der die Rückkehranweisung entfernt. Der try/catch funktioniert jetzt korrekt.

2

Ich sehe dieses Verhalten nicht. Ich habe in PowerShell ISE Folgendes ausgeführt und es werden die erwarteten Ergebnisse erzielt. Ist es möglich, dass die Fehler in der Datenbank nicht als Ausnahmen ausgelöst wurden? Ich glaube an SQL Server zum Beispiel, bestimmte Fehler unter einer bestimmten Fehlerstufe werden nicht als Ausnahmen zurück zum ADO.NET-Provider geworfen.

$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 

erzeugt die folgende:

Throw1.Try 
Throw1.Catch 
Throw1.Finally 
Error from Throw1 
+0

Ihr Kommentar zum SQL Server-Schweregrad kann etwas damit zu tun haben, obwohl es zu diesem Zeitpunkt noch nicht klar ist. Aber der innere catch-Block fängt den Fehler und wiederholt es. Es ist der Out-Catch-Block, der den Fehler nicht erfasst. Als Test schrieb ich in meiner insert-Anweisung einen Spaltennamen falsch, der einen ausreichend hohen Schweregrad erzeugen sollte, aber immer noch nicht im äußeren Fang gefangen wird. – user459866

+0

Haben Sie mein Skript ausgeführt? Auf meinem Computer wird es in der erwarteten Reihenfolge ausgeführt. Ich bin mir nicht sicher, was sonst in deinem Fall anders sein könnte. – Josh

1

Die Variable, die Sie festlegen möchten $ ErrorActionPreference ist, nicht mehr als $ ErrorPreference.

(Josh hat die richtige Variable.)

+0

Ich habe diese Korrektur gemacht, aber es hat nicht geholfen. Obwohl ich das nicht denken würde, habe ich eine Haupt-App in einer ps1-Datei und die Datenbankschnittstellen befinden sich in separaten Skriptdateien. Mein Verständnis ist die $ ErrrrorActionPreference-Spezifikation sollte für alle Skripte gelten, die von der Haupt-app.so aufgerufen werden, soweit ich es verstehe, sollte diese Struktur die Aktion des try/catch nicht ändern. – user459866