neo-project/neo-vm

Uncatchable exceptions

Closed this issue ยท 3 comments

The NeoVM allows to throw and catch exceptions in contract code. But, there are exceptions thrown from the NeoVM code itself that cannot be caught inside of the contract. For example here:

case OpCode.PICKITEM:
{
PrimitiveType key = Pop<PrimitiveType>();
var x = Pop();
switch (x)
{
case VMArray array:
{
int index = (int)key.GetInteger();
if (index < 0 || index >= array.Count)
throw new InvalidOperationException($"The value {index} is out of range.");
Push(array[index]);

In my opinion it is reasonable if the execution does not immediately FAULT in this case but would allow the contract dev to also catch and handle this kind of exception.

Any reasons why this is not so in the current state of the NeoVM?

@shargon @erikzhang @superboyiii can one of you shed some light here? ๐Ÿ˜„

I think it's a good idea. But we must do it carefully to ensure compatibility.

Couldn't this be a problem in some cross-contract scenario where contract A calls contract B with some data, B changes some stored state, then tries to handle the data, fails to do so ("out of range"), but then A catches the exception and finishes successfully keeping B state change? Maybe it's somewhat stretched, but this change looks suspicious and I'd like to ensure we're not missing something.