Powershell: Errors that terminate script due to -ErrorAction Stop do not show correct line number

Created on 2 Nov 2018  路  8Comments  路  Source: PowerShell/PowerShell

Steps to reproduce

PS > type .\error.ps1
[Cmdletbinding()]
param()

"hello"
"world"




    1/0

PS > .\error.ps1
hello
world
Attempted to divide by zero.
At D:\junk\error.ps1:10 char:5
+     1/0
+     ~~~
    + CategoryInfo          : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException

PS > $ErrorActionPreference = "Stop"
PS > .\error.ps1
hello
world
D:\junk\error.ps1 : Attempted to divide by zero.
At line:1 char:1
+ .\error.ps1
+ ~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [error.ps1], RuntimeException
    + FullyQualifiedErrorId : RuntimeException,error.ps1

Note incorrect line number being reported on second invocation when ErrorActionPreference equals "Stop"

This can also be reproduced by putting "$ErrorActionPreference = "Stop" at line 3 of the script.

I always set ErrorActionPreference to Stop at the start of my scripts, and also have ErrorActionPreference set to "Stop" always in my environment for improved robustness as I write scripts, As a result this issue is very problematic. The correct line number can be obtained by digging into $Error but that is a pain.

This started happening somewhere around the v5 release. Prior to that the correct line number was always reported. This can also be reproduced by using -ErrorAction Stop at a particular invocation, although that is a less compelling scenario.

Environment data

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.18272.1000
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.18272.1000
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WG-Engine

Most helpful comment

From the perspective of the script author having the correct line number is of course very important. That is primarily who the information is for, I would think. If the thinking is that the user doesn't care, which is a legit position, then the line number should be omitted entirely. But having incorrect information is bad for either case.

Omitting the information doesn't help anyone - I would argue it makes no difference to an end user (non-author), while it only hurts the author's ability to troubleshoot. Putting the correct info makes life substantially better for the author, while again making little to no difference to the end user.

All 8 comments

Note that the exception due to -ErrorAction Stop wraps the ErrorRecord that has the correct line number. Unless we can determine if there's value in wrapping the ErrorRecord, perhaps the best thing is just to not wrap so the right line number is shown without the user having to dig into the exception for it.

Wouldn't this result in deploying the contents of defined module functions as well?

In most cases an error that is emitted is due primarily to user input, if the script or module is designed well. As such, I would contend that it makes more sense to show the user just the command call as it does now, as for many third party module functions the innards are less relevant than the call to the command, which probably passed it the bad parameter in the first place... I think.

From the perspective of the script author having the correct line number is of course very important. That is primarily who the information is for, I would think. If the thinking is that the user doesn't care, which is a legit position, then the line number should be omitted entirely. But having incorrect information is bad for either case.

Omitting the information doesn't help anyone - I would argue it makes no difference to an end user (non-author), while it only hurts the author's ability to troubleshoot. Putting the correct info makes life substantially better for the author, while again making little to no difference to the end user.

I would like to re-iterate as well that I'm 100% certain this is a regression from at least v4, when I was doing extensive script authoring and never saw this problem. Unfortunately, I don't know exactly when the behavior changed.

Not wrapping the ErrorRecord with an exception when $ErrorActionPreference = Stop by cause unintended side effects. Another option to address the user experience issue is updating the default error view to show ErrorRecords and/or InnerExceptions https://github.com/PowerShell/PowerShell/issues/3647

Note also difference in the script name for two reported errors:

At D:\junk\error.ps1:10 char:5
At line:1 char:1

First thing points to line 10 in the script. Second one points to line 1 in the console, not in the script.

That is certainly an unusual discrepancy, indeed. Two sources of information here in the one error message! 馃槃

Save this example as a loc.ps1 file and run it::

function diverr {
    [CmdletBinding()]
    param()
    1/0  # line 4
}
diverr -ErrorAction Stop  # line 6

With -ErrorAction Stop error is reported in line 6. Without -ErrorAction Stop, error is reported in line 4.

Was this page helpful?
0 / 5 - 0 ratings