FAQ
Using panic-recover can be useful *within a package *to unwind the stack
and handle the panic at the top level. This technique is actually used
within the standard library. See encoding/json for an example
<https://github.com/golang/go/blob/c4135dac630d093e01f95ea651d7d4330f616cfb/src/encoding/json/decode.go#L149-L169>
:

func (d *decodeState) unmarshal(v interface{}) (err error) {
defer func() {
if r := recover(); r != nil {
if _, ok := r.(runtime.Error); ok {
panic(r)
}
err = r.(error)
}
}()

...
}


Note, that the logic explicitly checks for a runtime.Error (like
out-of-bounds) and re-panics those and assume everything else in a error.

Your approach (with using a panicErr struct) is probably better because it
narrows the scope on exactly what is caught.

JT
On Monday, January 11, 2016 at 9:29:30 AM UTC-8, Paul Borman wrote:

When I do this I use a specific type, for example

type panicErr struct {
err error
}

then panic(panicErr{errors.New("It's me!")})

full example: http://play.golang.org/p/ZzqctFqDNd

The advantage here is that you preserve actual panics and only catch what
you explicitly mean to catch. Of course, you can use any type, not just
something that uses and error.

-Paul

On Sat, Jan 9, 2016 at 5:13 PM, Roberto Zanotto <roby...@gmail.com
<javascript:>> wrote:
One downside is that you turn "real panics" (a bug, like an unexpected
index out of bounds) into an error.
If you need to know the function where the error originated, log package
does that for you, you can even have the precise line number.

On Sunday, January 10, 2016 at 1:26:05 AM UTC+1, Alain Vehent wrote:

Hello Gophers,

"Don't panic.", says http://go-proverbs.github.io/

I often panic inside a function with a defer block to recover and
transform it into an error. I haven't seen that kind of code (see
below) very often, and I'm wondering why. I like how it lets me
prepend the function name, which makes diagnosis easier when
multiple layers of functions are traversed. A poor's man
stacktrace, of sorts. Is this a bad pattern?

package main
import (
"encoding/json"
"fmt"
)
func main() {
fmt.Println(dontpanic())
}

func dontpanic() (err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("dontpanic() -> %v", e)
}
}()
err = json.Unmarshal([]byte("{{{"), nil)
if err != nil {
panic(err)
}
return
}

- Julien
--
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 <javascript:>.
For more options, visit https://groups.google.com/d/optout.
--
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.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

Discussion Posts

Previous

Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 4 of 12 | next ›
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJan 10, '16 at 12:25a
activeJan 12, '16 at 9:56p
posts12
users9
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase