2010-12-16 318 views
1

J'ai une instruction try-catch dans une instruction try-catch. Le catch interne intercepte l'erreur, mais le lancer ne provoque pas l'erreur dans l'instruction catch. Breifly, mon script est formaté similaire à:Powershell try/catch renvoyer ne pas propager l'erreur (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 
    } 
} 

Quand je courais le script il n'y avait pas d'erreurs, mais j'ai remarqué la base de données SQL Server que je tentais de remplir été données manquantes. Lorsque j'ai relancé le script dans le débogage, la fonction 'putStuffInDB' avait une erreur qui a été interceptée dans le bloc catch. Mais quand je suis intervenu, le message n'a pas été «jeté» au bloc catch externe, mais a traité le bloc finally et s'est terminé.

Il me manque évidemment quelque chose que je ne vois pas. J'ai utilisé la construction en C# dans le passé et n'ai jamais eu de problèmes avec les erreurs qui ont été 'passées' au bloc catch externe.

Répondre

1

j'ai réalisé que le problème était de mon propre fait. Dans les fonctions POSH pour créer les entrées SQLServer j'ai retourné la clé primaire de l'ensemble de données créé. La conception des fonctions était telle que la fonction retournerait la clé primaire. L'erreur de conception était que j'ai mis une déclaration de retour dans le bloc finally qui a remplacé le retour au catch externe. J'ai changé le design en supprimant la déclaration de retour. Le try/catch fonctionne maintenant correctement.

2

Je ne vois pas ce comportement. J'ai exécuté ce qui suit dans PowerShell ISE et il produit les résultats attendus. Est-il possible que les erreurs dans la base de données n'aient pas été considérées comme des exceptions? Je crois en SQL Server par exemple, certaines erreurs sous un niveau d'erreur donné ne sont pas renvoyées en tant qu'exceptions au fournisseur ADO.NET.

$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 

produit les points suivants:

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

Votre commentaire sur le niveau de gravité de SQL Server peut être associé à ce problème, même s'il n'est pas clair à ce stade. Mais, le bloc de capture interne attrape l'erreur et la repousse. C'est le bloc catch qui n'attrape pas l'erreur. En tant que test, dans ma déclaration d'insertion, j'ai mal orthographié un nom de colonne qui devrait générer un niveau de gravité suffisamment élevé, mais qui ne soit toujours pas pris dans le catch externe. – user459866

+0

Avez-vous exécuté mon script? Sur ma machine, il s'exécute dans l'ordre attendu. Je ne suis pas sûr de ce qui pourrait être différent dans votre cas. – Josh

1

La variable que vous souhaitez définir est $ ErrorActionPreference, pas ErrorPreference $.

(Josh positionniez la variable à droite.)

+0

J'ai fait cette correction, mais cela n'a pas aidé. Bien que je ne le pense pas, j'ai une application principale dans un fichier ps1 et les interfaces de base de données sont dans des fichiers de script distincts. Ma compréhension est la spécification $ ErrrrorActionPreference devrait s'appliquer à tous les scripts qui sont appelés par l'application principale.so autant que je le comprends, cette structure ne devrait pas modifier l'action de l'essai/catch. – user459866