从函数和调用者到终端的 Golang 错误处理

我想问一下错误处理的最佳实践,假设我有以下读取文件解析它的函数,当找不到文件并且解组失败时,它可能返回两种类型的错误


func Parse(source string) (bma.Bma, error) {

    file, err := ioutil.ReadFile(source + "bma.yaml")

    m := bma.Bma{}

    if err != nil {

        logs.Error("Not able to read the bma file")

        return m, err

    }

    err = yaml.Unmarshal([]byte(file), &m)

    if err != nil {

        logs.Error("Not able to unmarshal the bma file ")

        return m, err

    }

    return m, err

}

现在如果我调用这个函数并且有错误我也打印这个错误,该程序是 CLI 程序所以我认为如果出现问题会打印太多错误,可以吗,或者有更好的方法吗?


bma ,err := Parse("path")

    if err != nil {

        logs.Error("Error while parsing ")

        return m, err

    }


慕斯王
浏览 93回答 2
2回答

温温酱

我认为您要问的更多是关于何时打印错误,而不是何时处理或不处理错误。就我而言,如果我认为它们将来对我有用,我喜欢打印所有可以打印的日志。在您的情况下,消息可能logs.Error("Error while parsing ")过于冗长,因为您没有在那里显示任何详细信息。您可以考虑的其他方法是将您的自定义错误返回到顶层函数而不是更深层次的函数,并且只在那里显示日志消息。在示例的情况下应该是这样的:func main() {    bma, err := Parse("path")    if err != nil {        log.Println(err)        return    }}func Parse(source string) (bma.Bma, error) {    file, err := ioutil.ReadFile(source + "bma.yaml")    m := bma.Bma{}    if err != nil {        return m, fmt.Errorf("Not able to read the bma file: %s", err.Error())    }    err = yaml.Unmarshal([]byte(file), &m)    if err != nil {        return m, fmt.Errorf("Not able to unmarshal the bma file: %s", err.Error())    }    return m, err}

弑天下

package mainimport (    "fmt"    "log"    "os")func main() {    fileName := "main.go"    err := parse(fileName)    if err != nil {        log.Println(err)    }    log.Println(parse2(fileName))    log.Println(parse3(fileName))    //Incase of library one need to create new errors and export them    //see error.go file of some stdlib packages for some example}func parse(s string) error {    _, err := os.Open(s + "t") // fails    if err != nil {        // no need to add any custom err information,        // as err contains required details (action, fileName, error)        return err    }    return nil}func parse2(s string) error {    // Incase you must handle errors    _, err := os.Open(s + "t") // fails    if err != nil {        err = (err.(*os.PathError)).Err //only, if you must handle it        if err == os.ErrPermission {            //send notification to developer, about user        } else if err == os.ErrNotExist {            //user is so irresponsible, block him        } else if os.IsNotExist(err) {            fmt.Println("found the cause")        }        return err    }    return nil}func parse3(s string) error {    err := badError(s)    if err != nil {        // wrap error with required context information,        // if err doesn't return proper error        // or if you have more useful information        return fmt.Errorf("%s ,%s", s, err)    }    return nil}func badError(s string) error {    return fmt.Errorf("badError,I'm not saying why it failed, and what's the argument which caused me to fail, and making error without actually any content")}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go