cxm
cxm

Reputation: 33

How can i catch the runtime.errorString in recover()?

I try to catch the panic

func test(/*some input*/) (output string,err111 error) {
    defer func(){
        if err := recover(); err != nil {
            output = ""
            err111 = errors.New(err.(string))
        }
    }()
    ....
}

but goroutine tell me

interface conversion: interface {} is runtime.errorString, not string

how can I dump the recover() error and return it?

Upvotes: 3

Views: 2133

Answers (2)

WeakPointer
WeakPointer

Reputation: 3302

The type assertion to string failed because the type was something else. The type was an error (which is itself an interface that guarantees the Error method). Generally a type switch statement can help the code sort through different recover responses if that's desirable. Here's a medium length example. Note the runtime.Error case isn't necessary because a runtime.Error satisfies an error.

func foo(fn func()) {
defer func() {
    if e := recover(); e != nil {
        switch e := e.(type) {
        case string:
            fmt.Println("recovered (string) panic:", e)
        case runtime.Error:
            fmt.Println("recovered (runtime.Error) panic:", e.Error())
        case error:
            fmt.Println("recovered (error) panic:", e.Error())
        default:
            fmt.Println("recovered (default) panic:", e)
        }
        fmt.Println(string(debug.Stack()))
        return
    }
    fmt.Println("no panic recovered")
}()
fn()

}

Upvotes: 4

Vincent
Vincent

Reputation: 69

You cannot using type assertion like errors.New(err.(string)) cuz string is a underlying type which does not implement error interface.

So if you want to catch runtime.errorString panic. Maybe an unformal way is using reflection like :

if reflect.TypeOf(err).String() == "*errors.errorString" {
    // do something
}

Upvotes: 2

Related Questions