vm: throw unhandled exception with message instead of panic

The result is the same HALT state, but the exception message is the real
one got from user. Changes ported from C#:

1. Throw exception: 59b8ac73d2/src/neo-vm/ExecutionEngine.cs (L1448)
2. Prettify message: https://github.com/neo-project/neo-vm/blob/master/src/neo-vm/VMUnhandledException.cs#L28

The result is that instead of
```
2021-03-31T17:02:54.508+0300	WARN	contract invocation failed	{"tx": "2aefeb705f3a609df8767d9b45e036b9dd1eb77407e5732375981915668889b8", "block": 30640, "error": "error encountered at instruction 970 (THROW): runtime error: invalid memory address or nil pointer dereference"}
```

we'll get
```
2021-03-31T17:33:56.299+0300	WARN	contract invocation failed	{"tx": "2aefeb705f3a609df8767d9b45e036b9dd1eb77407e5732375981915668889b8", "block": 30640, "error": "error encountered at instruction 970 (THROW): unhandled exception: No authorization."}
```
in the node logs.
This commit is contained in:
Anna Shaleva 2021-03-31 17:17:54 +03:00
parent 93530fa8fa
commit f57187e611

View file

@ -1602,8 +1602,32 @@ func (v *VM) handleException() {
}
pop++
ictxv = ictxv.Next()
if ictxv == nil {
break
}
ictx = ictxv.Value().(*Context)
}
throwUnhandledException(v.uncaughtException)
}
// throwUnhandledException gets exception message from the provided stackitem and panics.
func throwUnhandledException(item stackitem.Item) {
msg := "unhandled exception"
switch item.Type() {
case stackitem.ArrayT:
if arr := item.Value().([]stackitem.Item); len(arr) > 0 {
data, err := arr[0].TryBytes()
if err == nil {
msg = fmt.Sprintf("%s: %q", msg, string(data))
}
}
default:
data, err := item.TryBytes()
if err == nil {
msg = fmt.Sprintf("%s: %q", msg, string(data))
}
}
panic(msg)
}
// CheckMultisigPar checks if sigs contains sufficient valid signatures.