2012-07-11 11 views
7

Sto riscontrando un problema particolare con Powershell. Sto rilevando un'eccezione in un blocco catch, ma l'oggetto $ Error globale non viene popolato.

Un esempio banale, quando ciò si comportano come previsto è questo:

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)" 
    } 
} 

uscita è come ci si aspetterebbe se si chiama Bar

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

Il codice che sto avendo problemi con è quasi identico, tranne che carica Foo da un modulo. Non so se questo è un bug, o semplicemente qualcosa che non capisco (dovrà controllare il mio PowerShell in Action libro!)

Se salvo Foo fuori ad un modulo - 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 

Poi eseguire le seguenti

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

io alla fine con

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

noti che Foo non vede più un tutte le modifiche apportate a $ Errore. Quindi il modulo-ificazione del codice sta cambiando il comportamento di propagazione degli errori. Qualcuno può entrare in sintonia con il ragionamento alla base di questo?

Devo notare che posso ottenere l'eccezione specifica rilevata tramite la variabile automatica $ _, ma sto cercando di ottenere una sospensione dell'intera collezione a questo punto nello stack di chiamate.

+0

Così la mia prima riga sopra è sbagliato .. la collezione $ errore globale viene modificato, ma il modulo con ambito di raccolta $ errori non è. –

risposta

7

Non l'avevo notato prima, ma forse la raccolta di errori $ è applicata al modulo come qualsiasi altra variabile. Provate a confrontare i valori delle seguenti due variabili in modo esplicito con ambito in punti chiave nel vostro script di test:

"Errors - Global: {0}; Module: {1}" -f $global:error.count, $script:error.count 

Fammi sapere come si ottiene.

+0

Potrebbe essere che $ error.clear() copia la variabile globale sull'ambito locale e lo cancella. –

+0

Un modo per ottenere la variabile Error nello scope del modulo sarebbe 'Get-Variable -Name Error -Scope 2'. @ End, visto che hai PS in azione potresti voler consultare la sezione '9.4.5. Come funzionano gli ambiti nei moduli di script'. –

+0

Ora mi sento un po 'stupido ... Non riesco a controllare al momento, ma sospetto che l'ambito sia il problema qui. Mi è sfuggito completamente la mente (il che è peggio, dal momento che ho qualche script $: vars di livello nel codice)! Ricontrollerei 9.4.5 - grazie Andy!Immagino che la particolarità sarebbe che l'accesso a $ Errore in un modulo non ha un ambito di validità ragionevole - dopo tutto, l'eccezione è emersa nel modulo, quindi si penserebbe che $ Errore sarebbe predefinito per l'array in cui sono stati raccolti gli errori dei moduli . –

9

Come menzionato da Ethan, è necessario guardare $ global: errore per vedere tutti gli errori. I moduli hanno sempre una variabile di errore $, ma è (per lo più) non utilizzata.

background: a un certo punto, abbiamo considerato gli errori di isolamento che si sono verificati nel codice del modulo nell'ambito del modulo ma alla fine abbiamo deciso di aggiungere tutti gli errori alla raccolta di errori globali poiché si tratta essenzialmente di un registro di errori (come un in memoria eventlog.) Sfortunatamente l'errore $ con scope del modulo non è stato rimosso prima del rilascio e quindi è necessario utilizzare il qualificatore di ambito globale per accedere alla variabile di errore $ "reale".

Bruce Payette, Microsoft Corporation

+0

Bruce - grazie per lo storico background. Questo è esattamente il tipo di informazioni che stavo cercando. –

Problemi correlati