-
Notifications
You must be signed in to change notification settings - Fork 382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: invoke user recover with implicit panics #3067
Conversation
Codecov ReportAttention: Patch coverage is 📢 Thoughts on this report? Let us know! |
can you please add some tests for this? |
I tried a fix similar to this one: #2484, but my approach wasn't preferred. They favor an indiscriminate runtime panic, which complicates things for me (it is possible, but need a refactoring). I see two options:
|
its still WIP |
5b8936f
to
ce6141c
Compare
tests added |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GG for this PR, it's a great improvement! However, I have a small issue regarding some cases where error handling with recover
doesn't seem to work as expected. For example, in the Gno Native packages, like this one:
package main
import "time"
func main() {
defer func() {
r := recover()
println("recover:", r)
}()
t := time.Now()
t.In(nil)
}
The issue here is that t.In(nil)
causes an error, but there's no recovery mechanism for this situation. However, since Gno Native will no longer be supported in the future, perhaps we don't need to handle this case at this point.
We also have cases where panic occurs when we inject Go code injected into a Gno package. For example, this code:
package test
import "std"
func main() {
defer func() {
r := recover()
println("recover:", r)
}()
banker := std.GetBanker(std.BankerTypeRealmSend)
banker.SendCoins(std.CurrentRealm().Addr(), "", std.Coins{{"ugnot", 2000000000}})
}
I’ve seen this kind of panic occur, and I’m unsure if this should be recoverable.
Also, consider this case:
package test
import "time"
func main() {
defer func() {
r := recover()
println("recover:", r)
}()
println(time.UTC == nil)
time.UTC = nil
}
This could also cause an issue, and I’m not sure if this is something we should be able to recover from.
Just wanted to raise these points, but again, great job on this PR!
some comments from @omarsy to be resolved, but otherwise LGTM. I'll approve this after. |
I think this worth discussing, the can you file another issue for this? @omarsy . |
Currently only explicit panic invocations are recovered in the user code. This PR covers the implicit panics that happen because of invalid operations. Associated [issue](gnolang#1148) This maintains the distinction between VM panics and user panics. Here is a list of possible runtime panics that we will cover. - [x] Out-of-Bounds Slice or Array Access - [x] Invalid Slice Indexing - [x] Division by Zero and MOD zero - [x] Type Assertion Failure - [x] Invalid Memory Allocation (bad call to make()) - [x] Out-of-Bounds String Indexing - [x] nil pointer dereference - [x] Write to a nil map Also, fixed a small bug with the builtint function `make`. It wasn't panicking when cap > len
Currently only explicit panic invocations are recovered in the user code.
This PR covers the implicit panics that happen because of invalid operations.
Associated issue
This maintains the distinction between VM panics and user panics.
Here is a list of possible runtime panics that we will cover.
Also, fixed a small bug with the builtint function
make
.It wasn't panicking when cap > len