Powershell: Get-Module is polluting $error (from formatting script) (when strict mode on)

Created on 21 Feb 2020  路  10Comments  路  Source: PowerShell/PowerShell

Seems this error comes from PowerShellCore_format_ps1xml.cs, from a handful of script blocks that look like this:

.AddScriptBlockColumn(@"
    if ($_.PrivateData -and $_.PrivateData.PSData)
    {
            $_.PrivateData.PSData.PreRelease
    }")

And of course PreRelease will not be defined for many (most?) modules that are out there.

Steps to reproduce

$error.Clear()
Set-StrictMode -Version Latest
New-ModuleManifest .\foo.psd1
ipmo .\foo.psd1
Get-Module foo | Out-Null
$error

Expected behavior

There should be no errors in $error, so there should be no output from the repro steps.

<no output>

Actual behavior

Error!

PropertyNotFoundException:
Line |
   4 |                                      $_.PrivateData.PSData.PreRelease
     |                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | The property 'PreRelease' cannot be found on this object. Verify that the property exists.

Although it doesn't show up in normal output, if you look into$error, it's there, making you wonder what went wrong. If you are looking into $error, you are probably trying to troubleshoot some problem, and you only want to see "real" errors in $error, and not be distracted or confused by things that just look like bugs in PowerShell.

Looking at it another way: I didn't run some command with -ErrorAction SilentlyContinue, and I didn't see an error from the command... so why in the world is an error showing up in $error? (That's why I described it as "polluting $error"--it seemingly is not an error; just the result of some internal PS bug scribbling useless and distracting information into it.)

Environment data

Name                           Value
----                           -----
PSVersion                      7.0.0-preview.7
PSEdition                      Core
GitCommitId                    7.0.0-preview.7
OS                             Microsoft Windows 10.0.19570
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Issue-Question

Most helpful comment

Actually @vexx32 has a point. Strict mode doesn't complain about indexing into null, and indexing a hashtable is faster than fake property access anyway, so this should just be:

.AddScriptBlockColumn("$_.PrivateData['PSData']['PreRelease']")

All 10 comments

I can repro. The only question is whether we think it's worth it to make things go slower for everyone in order to avoid errors for people who ... run in StrictMode 馃槚

Because the only way to write that which won't cause problems in strict mode requires a lot more testing:

if ($_.PrivateData -and 
    $_.PrivateData.ContainsKey("PSData") -and 
    $_.PrivateData.PSData.ContainsKey("PreRelease")) {
    $_.PrivateData.PSData.PreRelease
}

Easy fix though...

These are all hashtables, aren't they? Don't dictionaries typically just return null if you access a nonexistent key via the indexer?

Might be able to just swap the property syntax for key-access syntax and call it a day. 馃檪

The only question is whether we think it's worth it to make things go slower for everyone in order to avoid errors for people who ... run in StrictMode

IMO: it is absolutely worth it, yes. And in fact, if we don't keep the core "strict-mode clean", we might as well delete the feature. I think strict mode is very valuable, and I recommend it to everyone.

What's the status of those fancy new null-related operators? Because if those were turned on, you could say something like:

${_}?.PrivateData?['PSData']?['PreRelease']

@jazzdelightsme The title mentions $error but it is not discussed in the body. Can you expand on this? (or, I suppose, change the title if it's not really relevant?) Thanks.

@bpayette line 5 of the repro steps is "$error"

Actually @vexx32 has a point. Strict mode doesn't complain about indexing into null, and indexing a hashtable is faster than fake property access anyway, so this should just be:

.AddScriptBlockColumn("$_.PrivateData['PSData']['PreRelease']")

Strict mode doesn't complain about indexing into null

Yes, but if you go one leap beyond that, it is still an error (InvalidOperation: Cannot index into a null array), so it's still better to do the full checks (because what if there is no PSData element?).

@jazzdelightsme

line 5 of the repro steps is "$error"

Yes and the title also mentions polluting $error but it's not discussed in the expository text. $error is a running log of all the errors (except for -ignore) so I'm not sure what you mean by "polluted".

@Jaykul
WRT trying to access members that don't exist in a hash table, it'd expected ?. to handle this but it doesn't

@{a=13}?.zork
PropertyNotFoundException: The property 'zork' cannot be found on this object. Verify that the property exists.

It only works for $null which is unfortunate (ok - and a little bit weird.)

@bpayette okay, added some more explanation.

:tada:This issue was addressed in #11943, which has now been successfully released as v7.1.0-preview.4.:tada:

Handy links:

Was this page helpful?
0 / 5 - 0 ratings