-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: runtime: add parameters to recover to only return specific types #50424
Comments
It sounds like you’re trying to implement try/catch style exception handling in Go. |
@davecheney Yes, but without breaking the syntax of Go. |
Compare #47653 (comment), #28150. |
ISTM, this could basically almost be done as user function (baring bcmills's clever trick in #47653 (comment)), except that you can't quite rethrow the same panic as before if it turns out you didn't want to recover something. Why not fix that problem instead of adding a specific mechanism for types? Maybe have |
@carlmjohnson Why not? Usually we have our own definition of error types, which are different from runtime exceptions.And |
The fact that even the standard library uses this kind of wrappers is good evidence that this is a good idea. It is also very simple and backwards compatible. I like it. What exactly is there against this idea? |
I would also be fine with type mypanic struct {
ShouldRethrow bool
Value any
} Just being able to catch a particular type is fine, but what is really needed is the ability to say In general, there is nothing I can think of in Go's core that work only in a type specific way as is proposed in this issue. type MyError struct {
error
ShouldFrobinicate bool
}
if myerr := MyError{}; errors.As(err, &myerr) && myerr.ShouldFrobinicate {
// use myerr because it should be frobinicated …
}
// just use err as normal, even if it was a MyError… So, my vote FWIW is to create a more general mechanism instead of a type specific one. |
I would also tendentially prefer
(or, more in general, any time the re- I see this as potentially useful in libraries, but I'm also worried it would make debugging somewhat more confusing if the locations of the recover and of the re- |
Rewriting the trace could hide significant recovery attempt logic from the traceback. Currently all re-thrown panics are visible in tracebacks. Separately, I don't think capturing and replaying a trace via panic elsewhere should be allowed. Tracebacks are traditionally/conceptually related to a single callstack. Allowing splicing traces across separate call chains or goroutines mostly seems like it would confuse rather than aid understanding and troubleshooting. The more general approach probably isn't more generally useful. Specifying recovery types up front:
|
This proposal has been added to the active column of the proposals project |
This would be a fundamental change to the language that we are unlikely to make without very significant justification, which I don't see here. But I am intrigued by:
What is the problem with increasing the stack depth by 2? That makes clearer what is going on in the stack trace and doesn't seem like it hurts anything. |
Thank you for your attention! |
@letian0805 I see, there are too many irrelevant entries in the stack trace. Furthermore if there are a lot of recursive recover calls this could contribute to stack overflow problems. |
@beoran Yes, developers want to be able to quickly see which line is panic, and don't want to see a lot of useless information from top to bottom. |
Based on the discussion above, this proposal seems like a likely decline. |
I find these extra panic frame obfuscate the real issues and make troubleshooting harder. Yes, they represent the actual logic, but that's only since Go is unable to express the logic actually desired (only recover for a specific known type). If Go was able to catch a specific type (eg an internal parser error), it would result in much cleaner stack traces when some other panic occurs. |
If this existed I would sometimes use it to catch only a special error type but every other time I used recover I'd write |
No change in consensus, so declined. |
The
recover()
function supports parameters in order to recover only expected exceptions.For example:
For now, we can handle it like this temporarily:
However, each time Recover panic will increase the stack depth by 2. Therefore, a better way is to recover the specified exception by the runtime's recover function support parameters.
The text was updated successfully, but these errors were encountered: