Wednesday 15 September 2010

Powershell weird error handling behavior -



Powershell weird error handling behavior -

i found weird thing powershell errors. consider next script:

function produceerror { [cmdletbinding()] param() #write-error a1 #throw "a2" #a3.exe } function testerror { produceerror -ea stop produceerror -ea stop } testerror

i invoke produceerror cmdlet stop preference, no matter whether terminating or non-terminating error occurs, should behave same, doesn't.

this i'm observing powershell v3 (make sure a3.exe doesn't exist):

uncomment write-error: print a1 1 time , stop. uncomment throw: print a2 1 time , stop. uncomment a3.exe: complain twice not finding a3.exe.

why calling non-existent command seem cause non-terminating error, if set error preference stop? (i know set ea stop within testerror, want know cause of inconsistency within produceerror.)

this scoping issue, see about_scopes.

it's happening because implicitly using phone call operator & when calling a3.exe. can demonstrate changing code explicitly utilize it:

class="lang-powershell prettyprint-override">function produceerror { [cmdletbinding()] param() & a3.exe }

this produce same behavior. help page says:

when utilize phone call operator (&) run function or script, not added current scope. next illustration uses phone call operator:

class="lang-powershell prettyprint-override">& c:\scripts.sample.ps1

any aliases, functions, or variables sample.ps1 script creates not available in current scope.

to around that, can utilize invoke-expression or start-process:

class="lang-powershell prettyprint-override">function produceerror { [cmdletbinding()] param() invoke-expression a3.exe }

or

class="lang-powershell prettyprint-override">function produceerror { [cmdletbinding()] param() start-process a3.exe }

these should work way expect, because cmdlets in scope.

edit based on comment:

using phone call operator doesn't create kid scope (or subscope), it's new session:

sessions, modules, , nested prompts self-contained environments, not kid scopes of global scope in session.

sessions: session environment in windows powershell runs. when create session on remote computer, windows powershell establishes persistent connection remote computer. persistent connection lets utilize session multiple related commands.

because session contained environment, has own scope, session not kid scope of session in created. session starts own global scope. scope independent of global scope of session. can create kid scopes in session. example, can run script create kid scope in session.

powershell error-handling

No comments:

Post a Comment