Skip to content

Trap statement doesn't take effect when dot-sourced #5342

Description

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.'; exit 1 }

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.

Activity

  1. iSazonov commented on Nov 5, 2017

    @iSazonov
    Collaborator

    With t1.ps1

    . ./t2.ps1
    1 / 0
    Trap { '!!!!! Shame.'; exit 1 }
    'after'
    
    

    I get strange result too.

  2. mklement0 commented on Nov 5, 2017

    @mklement0
    ContributorAuthor

    Ilya (@iSazonov):

    Strange in what way?

    When I try your snippet, the in-script Trap takes 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.

  3. iSazonov commented on Nov 5, 2017

    @iSazonov
    Collaborator

    I don't see an error for previous command 1/0.

  4. added
    Issue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassif
    on Nov 9, 2017
  5. BrucePay commented on Mar 28, 2018

    @BrucePay
    Collaborator

    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

    PS[1] (39) > trap { Write-Host Hello }
    PS[1] (40) >
    

    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.

  6. BrucePay commented on Apr 2, 2018

    @BrucePay
    Collaborator

    No additional updates so I'm closing this.

  7. mklement0 commented on Apr 2, 2018

    @mklement0
    ContributorAuthor

    Steve Lee (@SteveL-MSFT): Can you please add the Documentation Needed label so that Bruce Payette (@BrucePay)'s explanation can be rescued from obscurity?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassifResolution-By DesignThe reported behavior is by design.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions