You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Trap statement doesn't take effect when dot-sourced #5342
Defining a Trap statement via a dot-sourced script does not work, which is surprising, given that dot-sourcing[1] is generally equivalent to including the referenced script's content directly in a script.
Steps to reproduce
Setup:
Content of t1.ps1:
. ./t2.ps1
1/0'after'
Content of t2.ps1:
Trap { 'Shame.'; exit1 }
Command that reproduces the symptom:
> ./t1.ps1`
Expected behavior
Shame.
The Trap handler should take effect, output the specified string, and exit with exit code 1.
Actual behavior
Attempted to divide by zero.
At /Users/jdoe/t1.ps1:5 char:1
+ 1 / 0
+ ~~~~~
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
after
The Trap handler was ignored altogether, due to being dot-sourced rather than being included directly in the script.
Environment data
PowerShell Core v6.0.0-beta.9 on macOS 10.13
PowerShell Core v6.0.0-beta.9 on Ubuntu 16.04.3 LTS
PowerShell Core v6.0.0-beta.9 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)
Windows PowerShell v5.1.15063.674 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)
[1] Nomenclature quibble: Why is . called the dot-sourcing operator, and not just sourcing operator? Contrast this with &, the call operator, which is mercifully not called the "ampersand call operator". Including the somewhat arbitrary syntactic form in the name seems unnecessary.
Michael Klement (@mklement0)Ilya (@iSazonov)trap is a lexical construct, scoped to the compile unit (i.e. the script). This is why dot-sourcing a file with a trap statement doesn't introduce a trap into the caller's environment. When the dot-sourced script exits, its traps are removed. This is also why defining a trap by itself on the command line
appears to do nothing. The command executes and then the trap is removed.
NOTE: In V1, we did consider allowing traps defined in dot-sourced scripts or on the command line to persist in the caller's environment however this would have required additional commands to enumerate and manage traps. Due to a lack of time/resources, this was not implemented for V1 and it would be a significant breaking change to do so now.
Activity
iSazonov commentedon Nov 5, 2017
With t1.ps1
I get strange result too.
mklement0 commentedon Nov 5, 2017
Ilya (@iSazonov):
Strange in what way?
When I try your snippet, the in-script
Traptakes effect (it's fine to place it after the offending statement), and the sourced one is still ignored.So it seems to me that both snippets demonstrate the same problem.
iSazonov commentedon Nov 5, 2017
I don't see an error for previous command
1/0.BrucePay commentedon Mar 28, 2018
Michael Klement (@mklement0) Ilya (@iSazonov)
trapis a lexical construct, scoped to the compile unit (i.e. the script). This is why dot-sourcing a file with atrapstatement doesn't introduce a trap into the caller's environment. When the dot-sourced script exits, its traps are removed. This is also why defining atrapby itself on the command lineappears to do nothing. The command executes and then the trap is removed.
NOTE: In V1, we did consider allowing traps defined in dot-sourced scripts or on the command line to persist in the caller's environment however this would have required additional commands to enumerate and manage traps. Due to a lack of time/resources, this was not implemented for V1 and it would be a significant breaking change to do so now.
BrucePay commentedon Apr 2, 2018
No additional updates so I'm closing this.
mklement0 commentedon Apr 2, 2018
Steve Lee (@SteveL-MSFT): Can you please add the
Documentation Neededlabel so that Bruce Payette (@BrucePay)'s explanation can be rescued from obscurity?Fix `trap` error logging by moving to individual scripts
Fix `trap` error logging by moving to individual scripts (#45354)