(PS: I've only learned about runtime.Goexit after I came up with the sentinel-panic pattern. I've been thinking for a while, that it is probably a better choice, for various reasons. And after testing it out, <https://play.golang.org/p/ScfFGr5IxX0> I do think it's strictly superior. So you should probably disregard the sentinel-panic idea, runtime.Goexit seems strictly superior)
On Tue, Feb 23, 2021 at 1:49 PM Axel Wagner <[email protected]> wrote: > On Tue, Feb 23, 2021 at 1:10 PM Kevin Chadwick <[email protected]> > wrote: > >> Is it possible to call panic in a way that does not kill the process like >> os.Exit, but without log pollution? > > > > I am solely thinking of manually instigated panics, so a noop panic called >> something like terminate? >> > > You can `recover`. It's possible to use a private sentinel value to detect > if a panic was caused by a known code-path or not and re-panic if not. For > example, I sometimes use this pattern > <https://play.golang.org/p/7qPkZEerle5> in parsers. It does have some > downsides though - for example, if you do have to re-panic, you lose some > context about where the bug happened. > > There is also runtime.Goexit <https://golang.org/pkg/runtime/#Goexit>, > which aborts a running goroutine, calling deferred handlers, but doesn't > exit the program and doesn't log anything (and can't be recovered). It's > used by `t.Fatal` and friends. > However, one thing to keep in mind is that this *might* cause problems if > code isn't prepared for it. For example, it's natural to assume that a > function either panics or runs to completion. And it might assume that it's > fine to leave corrupted state because a panic should crash the program - or > it might use `recover` to check if a panic occurred and conclude that none > did when it gets `nil`. Technically, such code is wrong - it makes wrong > assumptions about Go, like forgetting that panics exist, that Goexit exists > or that panic(nil) is possible. > > But buggy or not - they are natural assumptions to make and such code does > exist and you might trigger subtle bugs by doing anything of the above. So > in general, I would prefer orderly control flow, unless you can make > reasonable assumptions about the code you are skipping over. For example, > it's probably fine to trigger a bug like that in test code, because at > worst, it will make the test fail (correctly detecting a bug) or the > process will exit when the test is finished, cleaning up things. For > example, I'm fine using the sentinel-panic pattern in parsers, because I > control the code it's calling into and can make sure it only modifies state > in a way compatible with the pattern. > > For something like a logging framework, I would strongly prefer orderly > control flow, crashing panics or no error checking. The code it's used in > is largely unknown. And either logging is considered critical, in which > case it needs to be checked or should crash if it fails, or it's not > considered critical, in which case there's nothing to be done about an > error and you might as well ignore it. > > >> Or is this bad practice, even when a program is in good operational order >> when instigated, as the OS is better at cleanup? >> >> -- >> 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 [email protected]. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/golang-nuts/3A8FA632-4991-4245-ABB3-8F4CE1164703%40gmail.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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAEkBMfHmAFGt6Ej-rguraZAx_at6Lh8KB-1dBMXZjdOyF11UZQ%40mail.gmail.com.
