Illegal coercion operation producing inconsistent error/exception behavior depending on scope
Consider this example, a ps1 script test.ps1
function MyTestFunction
{
[CmdletBinding()]
param ()
try
{
[bool]$functionBool= $null
}
catch {throw $_}
Get-Variable 'functionBool'
}
MyTestFunction -ErrorAction Stop
[bool]$scriptBool= $null
- There are 2x illegal variable declarations in the above example (
System.Booleanis a non-nullable type).
Resulting output when this .ps1 script is run by:
- Dot-sourcing
.the scriptName Value ---- ----- functionBool False Cannot convert value "" to type "System.Boolean". Boolean parameters accept only Boolean values and numbers, such as $True, $False, 1 or 0. At C:\scripts\test.ps1:17 char:1 + [bool]$scriptBool = $null + ~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException + FullyQualifiedErrorId : RuntimeException$functionBoolis transformed to$false- No exception is thrown
$scriptBoolis not transformed- An (expected)
ArgumentTransformationMetadataExceptionexception is thrown
- An (expected)
- Using the call operator
&Name Value ---- ----- functionBool False- No exception is thrown at all, for either operation.
As expected, doing the same operation in the global scope in the CLI throws an exception:
PS C:\> [bool]$scriptBool = $null Cannot convert value "" to type "System.Boolean". Boolean parameters accept only Boolean values and numbers, such as $True, $False, 1 or 0. At line:1 char:1 + [bool]$scriptBool = $null + ~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException + FullyQualifiedErrorId : RuntimeException
Questions
- What am I not understanding about scopes and PowerShell's behavior in regards to type coercion, specifically the example mentioned at the top?
- In other words, why doesn't the line
[bool]$functionBool= $nullthrow an exception?
- In other words, why doesn't the line
- If I set a breakpoint on line #8 (where
[bool]$functionBool= $nullis declared) in VS Code/ISE and step through, program flow will end up in the catch block of theMyTestFunctionfunction.- Confusingly, removing the breakpoint produces a different result where the
catch{}block is not executed.
- Confusingly, removing the breakpoint produces a different result where the