Description
Note: The root cause is the same as for #4594, which describes it in detail; the Start-Transcript
-focused #10994 may be related too.
In short: the asynchronous behavior of implicitly applied Format-Table
formatting (for types without explicit format data) has surprising side effects; while #4594 only describes more or less cosmetic issues, there is potential data loss here:
If a throw
or exit
statement comes before the asynchronous table output's delay has elapsed, that output as well as any subsequent output is never displayed.
While this is disconcerting enough interactively, it is very problematic when output from a call to PowerShell's CLI is being logged.
This SO question shows that the problem happens in real life; that question's author made the following points there:
-
checking the log of an important overnight job run, key info about things happening just before an error is missing because of this bug. Also the missing info makes it look like the error occurred at a different point in the script.
-
introducing an async delay seems like cheating. [...] If they really wanted to wait 300ms to sample data, that delay should occur synchronously.
The variant manifestation with exit
was discovered in this SO answer.
Steps to reproduce
With throw
pwsh -noprofile -c @'
'before'
[pscustomobject] @{ foo = 1 }
'after'
throw "error"
'@
Same symptom with exit
:
pwsh -noprofile -c @'
'before'
[pscustomobject] @{ foo = 1 }
'after'
exit
'@
Expected behavior
All objects output before the throw
statement should show, 'before'
, the table-formatted custom object, and 'after'
(ditto for the exit
variation, except for the error message):
before
foo
---
1
after
Exception:
Line |
4 | throw error
| ~~~~~~~~~~~
| ScriptHalted
Actual behavior
All output starting with the implicitly table-formatted [pscustomobject] @{ foo = 1 }
statement is lost:
before
Exception:
Line |
4 | throw error
| ~~~~~~~~~~~
| ScriptHalted
Environment data
PowerShell Core 7.1.0-rc.2