When adding a duplicate key to a hashtable using the add method, a MethodInvocationException arises:
50|PS(5.1.19041) C:\Users [220908-11:58:48]> $h = @{}
51|PS(5.1.19041) C:\Users [220908-11:58:51]> $h.add('a',$null)
52|PS(5.1.19041) C:\Users [220908-11:58:53]> $h.add('a',$null)
Exception calling "Add" with "2" argument(s): "Item has already been added. Key in dictionary: 'a' Key being added: 'a'"
At line:1 char:1
+ $h.add('a',$null)
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentException
I prepared a couple of functions to test whether this is a non-terminating or terminating error. The results seem conflicting. Here is my first function and test run:
function test-ht {
[cmdletbinding()]
param(
[hashtable]$ht,
[string]$addKey,
[string]$addValue,
[string]$msg
)
$ht.Add( $addKey, $addValue )
write-host "finished $msg"
}
$hash = @{}
test-ht -ht $hash -addKey 'test' -addValue '1' -msg 'trial 1'
test-ht -ht $hash -addKey 'test' -addValue '2' -msg 'trial 1 err'
test-ht -ht $hash -addKey 'test' -addValue '3' -msg 'trial 1 stop' -ErrorAction Stop
This outputs:
finished trial 1
Exception calling "Add" with "2" argument(s): "Item has already been added. Key in dictionary: 'test' Key being added: 'test'"
At line:10 char:5
+ $ht.Add( $addKey, $addValue )
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentException
finished trial 1 err
test-ht : Exception calling "Add" with "2" argument(s): "Item has already been added. Key in dictionary: 'test' Key being added: 'test'"
At line:18 char:1
+ test-ht -ht $hash -addKey 'test' -addValue '3' -msg 'trial 1 stop' -E ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [test-ht], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentException,test-ht
The 2nd command with -msg 'trial 1 err' seems to suggest it is a non-terminating error: the function prints the exception but still writes out its finished message. When I force it to -ErrorAction Stop, the finished message does not appear. This seems like normal behavior for a non-terminating error to me.
Then I run the second test, which is the same as above, except the .Add method is embedded in a try/catch statement:
function test-ht2 {
[cmdletbinding()]
param(
[hashtable]$ht,
[string]$addKey,
[string]$addValue,
[string]$msg
)
try {$ht.Add( $addKey, $addValue )} catch{}
write-host "finished $msg"
}
$hash2 = @{}
test-ht2 -ht $hash2 -addKey 'test' -addValue '1' -msg 'trial 2'
test-ht2 -ht $hash2 -addKey 'test' -addValue '2' -msg 'trial 2 err'
This outputs:
finished trial 2
finished trial 2 err
Here, the catch suppresses the error. This suggests a terminating error to me, as catch does not suppress non-terminating errors, e.g.,
55|PS(5.1.19041) C:\Users [220908-12:05:36]> gci C:/missing; write-host 'finished'
gci : Cannot find path 'C:\missing' because it does not exist.
At line:1 char:1
+ gci C:/missing; write-host 'finished'
+ ~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\missing:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
finished
56|PS(5.1.19041) C:\Users [220908-12:05:42]> try {gci C:/missing; write-host 'finished'} catch {}
gci : Cannot find path 'C:\missing' because it does not exist.
At line:1 char:6
+ try {gci C:/missing; write-host 'finished'} catch {}
+ ~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\missing:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
finished
In summary, in the first run with test-ht, the -msg 'trial 1 err' printed the exception and continued, as if it were non-terminating. In the second run with test-ht2 and the same function calls, the exception is suppressed by catch, as if it were a terminating error.
My questions:
- Is this error non-terminating or terminating?
- If it is non-terminating, why does the catch suppress the exception message?
- If it is terminating, why does
test-htrun to completion when adding a duplicate key?