--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
I'd say that recover() is not a problem but, instead, a symptom of panic() being available to developers. I'd flip the title and say panic() should be considered harmful. To quote from https://blog.golang.org/defer-panic-and-recover :> The process continues up the stack until all functions in the current goroutine have returned, at which point the program crashes
-j
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
Your point 3 misses an important practical detail. Packages that use recover internally call panic with an identifiable type and the recover code checks whether the type is the expected one and, if not, panics again, thus behaving like any other unexpected problem.See encoding/gob/error.go for an example.More generally, recover is excellent for isolation of errors in multi-client servers.Even more generally, blanket statements about what to do or not do with the features of a programming language are too often taken as strict rules rather than thoughtful guidelines. "Don't use panic or recover" is an example. Panic and recover are the perfect tools for some problem and prohibiting them outright eliminates some powerful designs.-rob
On Mon, Apr 24, 2017 at 5:40 AM, 'Axel Wagner' via golang-nuts <golan...@googlegroups.com> wrote:
My 2¢:1. panic if an API is clearly used wrongly. If a dev chose to not read the docs for this one function and ignore how it's supposed to be called, then what else have they not read the docs of? If you can detect that a program is incorrect, failing loudly seems the right thing to do2. Do not panic, if an API is used correctly; this includes failing syscalls that you'd expect to be correct if the API is correctly - your expectations might be wrong. Return an error on non-code related problems.3. Don't recover, pretty much universally. Even using it as a control-flow mechanism seems broken to me; it would hide actual programming errors that *should* crash4. If you are using a library that panics and you dislike that, I see two possible root-causes; a) you are using a library that badly coded (according to 2) or b) your program is buggy. In either case, the correct solution doesn't seem to paper over either bug, but to complain loudly so it gets fixed.5. Be prepared for your stuff crashing, from a dev-induced panic or a runtime-induced panic.And as a preventative measure: I say this as a person who was oncall while a large service, written in a memory safe language, crashed globally and took our service out. I know it's hard to be prepared for these things and to recover from them, but I still believe that crashing is the right thing to do. You can not prevent crashes, even globally synchronized ones, to happen. Because programmers are just humans and humans are fallible and stuff happens. You need to be prepared to deal with human failures.
On Mon, Apr 24, 2017 at 2:24 PM, Sokolov Yura <funny....@gmail.com> wrote:
> Notice that real unrecoverable errors are not subject to defer/recover() at all.If so, then how should I raise unrecoverable error, if I really know that it is unrecoverable?Something like C style assert(): "guy, something goes completely wrong, and it ismuch better to stop functioning than corrupt your data further"> It's sometimes a perfectly valid and quite reasonable approach to defer a recover() in an API function and panic(forWhateverReason) somewhere down the call chain.> A recursive descent parser may get much simpler and easier to code, for example.I don't agree. I call it "abusing". In absence of other comfortable ways, panic is abused to unwind stack fast (upto recover).I could be mistaken.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
-j
Your point 3 misses an important practical detail. Packages that use recover internally call panic with an identifiable type and the recover code checks whether the type is the expected one and, if not, panics again, thus behaving like any other unexpected problem.
In this example we're considering panic as a mechanism of preventing otherwise avoidable code bugs. What happens when the same code begins silencing panics and continuing on? Do we add a new level of panic that overcomes the normal recovery method? The fundamental assertion being made by panic advocates is that you know better than I when my program should end and you want some mechanism to enforce that opinion on me.I'll argue that sticking to idiomatic errors returned by function calls combined with static analysis tools, like errcheck, are sufficient in solving for all scenarios where panic might otherwise be used to signal an error state.
If you want to use panic internally within an API that's completely acceptable so long as that panic is never exposed beyond the API boundary. To quote the golang blog on the subject:The convention in the Go libraries is that even when a package uses panic internally, its external API still presents explicit error return values.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
I do think that panic should be avoided whenever possible. I had a third party library that panicked and crashed my application during the production run. If it were to return errors instead, I could have anticipated the problem and handled the situation with a bit more grace. The problem with panic is that it isn't obvious from the method signature that there is a possible alternate path. The author does not always document it. Thus, this hidden path is often unhandled and crashes the application. This may be acceptable during development phase, but not in the production run.
I am pretty sure panic has its uses, but at the moment there are still people who use panic as a rare error. An error is an error. If you can return an error, you should return an error, even if it is rare or near impossible to happen. The fact that panic is used as a rare error makes it even dangerous because they represent the corner cases that are often unanticipated by the developers.
Nowadays I just wrap any third party library and use recover in case if any of them suddenly goes into shock and panic.
On Monday, April 24, 2017 at 4:02:55 PM UTC+7, Sokolov Yura wrote:Good day, people.Title is a bit controversial :-)I want to ask:- how useful `recover` for you?- Don't you think it is a bit "dangerous"?I mean: panic usually means programmer error, so if it happens, thenprogram behaves incorrectly, and there is always a chance of seriousstate corruption. So, is there reason to recover at all?Also, presence of `recover` complicates implementation of `defer`.
I believe, it could be optimized much harder in absence of `recover`(i.e. if program always exits on panic).I could be mistaken.Yura.
--
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
I think those are all excellent things to do. They do not preclude the use of recovering from a panic to assist (emphasis on assist - it is certainly no silver bullet) in achieving fault tolerance.Assuming a web service that needs to be highly available, crashing the entire process due to one misbehaved goroutine is irresponsible. There can be thousands of other active requests in flight that could fail gracefully as well, or succeed at their task.In this scenario, I believe a well behaved program should
- clearly log all information about the fault
- remove itself from a load balancer
- alert some monitoring program that it has experienced critical errors
- depending on widespread severity, have a monitoring program alert a human to inspect it
On Wednesday, 26 April 2017 10:57:58 UTC+10, Chris G wrote:I think those are all excellent things to do. They do not preclude the use of recovering from a panic to assist (emphasis on assist - it is certainly no silver bullet) in achieving fault tolerance.Assuming a web service that needs to be highly available, crashing the entire process due to one misbehaved goroutine is irresponsible. There can be thousands of other active requests in flight that could fail gracefully as well, or succeed at their task.In this scenario, I believe a well behaved program should
- clearly log all information about the fault
panic does that
- remove itself from a load balancer
your load balancer should detect that; it shouldn't wait to be told that a backend has failed.
- alert some monitoring program that it has experienced critical errors
The monitoring program should detect that the process exited; not the other way around.
- depending on widespread severity, have a monitoring program alert a human to inspect it
Same; relying on a malfunctioning program to report its failure is like asking a sick human to perform their own surgery.
There are a host of other reasons that can take a server offline abruptly. It seems like a odd misallocation of resources to try to prevent one specific case - a goroutine panics due to a programming error or input validation failure -- both which are far better addressed with testing.
To try to postpone the exit of a program after a critical error to me implies a much more complex testing and validation process that has identified all the shared state in the program and verified that it is correct in the case that a panic is caught.
To me it seems simpler and more likely to have the root cause of the panic addressed to just let the program crash. The alternative, somehow firewalling the crash, and its effects on the internal state of your program, sounds unworkably optimistic.
> Yes, and then crashes the program. In the scenario I described, with thousands of other requests in flight that meet an abrubt end. That could be incredibly costly, even if it's been planned forThere are a host of other reasons that can take a server offline abruptly. It seems like a odd misallocation of resources to try to prevent one specific case - a goroutine panics due to a programming error or input validation failure -- both which are far better addressed with testing.
To try to postpone the exit of a program after a critical error to me implies a much more complex testing and validation process that has identified all the shared state in the program and verified that it is correct in the case that a panic is caught.
To me it seems simpler and more likely to have the root cause of the panic addressed to just let the program crash. The alternative, somehow firewalling the crash, and its effects on the internal state of your program, sounds unworkably optimistic.
There's an implicit argument here that the panic is, in fact, the result of a critical error. This is my primary contention with the general use of panic(). There is no guarantee for me as the consumer of a panicking library that the panic in question is truly related to an unrecoverable exception state that can only be resolved by a process exit
I posit the question one last time: How can the author of shared code understand, in sufficient detail, all the possible ways that the code could be leverage such that she or he could determine, objectively, that any given process must stop when a particular error state is encountered?
> There are a host of other reasons that can take a server offline abruptly. It seems like a odd misallocation of resources to try to prevent one specific case.
This, generally, is the argument that "if you can't stop all exceptions then why bother to stop any?". Contrary to exception states such as my cloud provider has terminated my instance abruptly or my data center has lost power, panic() uses are entirely defined by developers and not strictly related to unrecoverable exception states. The process exit in the case of a panic is entirely preventable unlike a true, systemic failure. To say that panic leads to process termination and, therefore, panic is equivalent to all process termination events is fallacious. I stand firm that only the process developer knows when the process should exit.
To put it more succinctly: The idea that your exception state should stop my process is, well, that's just, like, your opinion, man.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/rW6LB-9N37I/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts+unsubscribe@googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/rW6LB-9N37I/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts+unsubscribe@googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
On Wednesday, 26 April 2017 10:57:58 UTC+10, Chris G wrote:I think those are all excellent things to do. They do not preclude the use of recovering from a panic to assist (emphasis on assist - it is certainly no silver bullet) in achieving fault tolerance.Assuming a web service that needs to be highly available, crashing the entire process due to one misbehaved goroutine is irresponsible. There can be thousands of other active requests in flight that could fail gracefully as well, or succeed at their task.In this scenario, I believe a well behaved program should
- clearly log all information about the fault
panic does that
Same; relying on a malfunctioning program to report its failure is like asking a sick human to perform their own surgery.
On Wed, Apr 26, 2017 at 3:07 AM, Dave Cheney <da...@cheney.net> wrote:
On Wednesday, 26 April 2017 10:57:58 UTC+10, Chris G wrote:I think those are all excellent things to do. They do not preclude the use of recovering from a panic to assist (emphasis on assist - it is certainly no silver bullet) in achieving fault tolerance.Assuming a web service that needs to be highly available, crashing the entire process due to one misbehaved goroutine is irresponsible. There can be thousands of other active requests in flight that could fail gracefully as well, or succeed at their task.In this scenario, I believe a well behaved program should
- clearly log all information about the fault
panic does thatNo, panic certainly does not do that. It prints the stack trace. A proper logger could add additional information about the program state at the point of the panic, which is not visible from the stack trace. It also might at least be reasonable to perform an auto-save before quitting.Same; relying on a malfunctioning program to report its failure is like asking a sick human to perform their own surgery.What makes you think that a panic implies that the whole program is malfunctioning?
A panic should certainly taken seriously, and the computation in which it happened should be aborted. But if you think of a functional programming style
-j
-j
No, panic certainly does not do that. It prints the stack trace. A proper logger could add additional information about the program state at the point of the panic, which is not visible from the stack trace. It also might at least be reasonable to perform an auto-save before quitting.
I want to ask:- how useful `recover` for you?
- Don't you think it is a bit "dangerous"?
Most languages, who stick with Exceptions, usually has two kind of exceptions:- "exception for regular error", i.e. wrong input, wrong system state, or for "control flow"- and "fatal exceptions",
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.