web-dev-qa-db-fra.com

Go: retour de report

Je veux renvoyer une erreur d'une fonction si elle panique (en Go):

func getReport(filename string) (rep report, err error) {
    rep.data = make(map[string]float64)

    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered in f", r)
            err, _ = r.(error)
            return nil, err
        }
    }()
    panic("Report format not recognized.")
    // rest of the getReport function, which can try to out-of-bound-access a slice
    ...
} 

Il me semble avoir mal compris le concept même de panique et de report. Quelqu'un peut-il m'éclairer?

41
jrichner

Dans une fonction différée, vous pouvez modifier les paramètres renvoyés, mais vous ne pouvez pas retourner un nouvel ensemble. Donc, un simple changement de ce que vous avez le fera fonctionner.

Il y a un autre problème avec ce que vous avez écrit, à savoir que vous avez paniqué avec un string mais que vous attendez un error dans votre assertion de type.

Voici un correctif pour les deux ( Play )

defer func() {
    if r := recover(); r != nil {
        fmt.Println("Recovered in f", r)
        // find out exactly what the error was and set err
        switch x := r.(type) {
        case string:
            err = errors.New(x)
        case error:
            err = x
        default:
            err = errors.New("Unknown panic")
        }
        // invalidate rep
        rep = nil
        // return the modified err and rep
    }
}()
61
Nick Craig-Wood

jetez un oeil à cela

package main

import "fmt"

func iWillPanic() {
    panic("ops, panic")
}
func runner() (s string) {
    rtnValue := ""
    defer func() {
        if r := recover(); r != nil {
            // and your logs or something here, log nothing with panic is not a good idea
            s = "don't panic" // modify the return value, and it will return
        }
    }()
    iWillPanic()
    return rtnValue
}

func main() {
    fmt.Println("Return Value:", runner())
}
3
fang jinxu