美文网首页golang
Go中有效的错误处理

Go中有效的错误处理

作者: devabel | 来源:发表于2018-03-24 23:21 被阅读26次

原文链接:https://morsmachine.dk/error-handling
翻译:devabel

介绍

Go得到很多批评的事情之一就是如何处理错误。尽管必须明确检查每个错误似乎令人望而生畏,但您可以采取一些措施来防范错误的错误处理。

以缩进流处理错误

在编写Go代码时,建议:

f, err := os.Open(path)
if err != nil {
    // handle error
}
// do stuff

不建议:

f, err := os.Open(path)
if err == nil {
    // do stuff
}
// handle error

这样,无错误的情况下,业务逻辑将直线顺序执行。

定义你的错误

当知道有错误发生的时候必须首先知道怎么传递错误。如果您的包可能以某种方式导致错误,那么您的用户可能有兴趣知道怎么造成了错误。要做到这一点,你只需要实现错误接口,就是这样简单的事情:

type Error string

func (e Error) Error() string { return string(e) }

使用您得包的用户现在可以通过执行类型断言来判断您的包是否导致错误

result, err := yourpackage.Foo()
if ype, ok := err.(yourpackage.Error); ok {
    // use ype to handle error
}

这也可以用来向用户公开结构化错误信息。

type ParseError struct {
    File  *File
    Error string
}

func (oe *OpenError) Error() string {
    // format error string here
}

func ParseFiles(files []*File) error {
    for _, f := range files {
        err := f.parse()
        if err != nil {
            return &OpenError{
                File:  f,
                Error: err.Error(),
            }
        }
    }
}

这样,您的用户现在可以分辨哪个文件无法解析。

尽管如此,你应该小心包装错误。当您包装错误时,信息可能会丢失。

var c net.Conn
f, err := DownloadFile(c, path)
switch e := err.(type) {
default:
    // this will get executed if err == nil
case net.Error:
    // close connection, not valid anymore
    c.Close()
    return e
case error:
    // if err is non-nil
    return err
}
// do other things.

如果你包装net.Error,这段代码将不会看到它是网络失败并重新使用无效连接。

一个好的经验法则是,如果你的软件包使用外部接口,不要将通过调用产生的错误包装起来。您的用户可能比您的更关心他们的错误。

状态错误

有时候您可能想要坚持发生错误,因为您可以延迟报告,或者您知道很快会再次报告。

第一种情况的一个好例子是bufio包。当bufio.Reader遇到错误时,它会一直等到错误发生,直到缓冲区被清空。只有这样它才会报告它。

第二种情况的一个好例子是go / loader。当使用导致错误的参数进行调用时,它会保留错误,因为它很可能会再次用相同的参数调用。

使用函数来避免重复
如果你有一个重复的错误处理,你可以使用一个函数。

func handleError(c net.Conn, err error) {
    // repeated error handling
}

func DoStuff(c net.Conn) error {
    f, err := downloadFile(c, path)
    if err != nil {
        handleError(c, err)
        return err
    }
    
    f, err := doOtherThing(c)
    if err != nil {
        handleError(c, err)
        return err
    }
}

另一种写作方式是

func handleError(c net.Conn, err error) {
    if err == nil {
        return
    }
    // repeated error handling
}

func DoStuff(c net.Conn) error {
    defer func() { handleError(c, err) }()
    f, err := downloadFile(c, path)
    if err != nil {
        return err
    }
    
    f, err := doOtherThing(c)
    if err != nil {
        return err
    }
}

就这样。
这就是它的全部。

相关文章

  • Go 语言基础——错误处理

    学习目标 掌握错误处理 掌握自定义错误处理 掌握defer关键字的使用 错误处理 GO没有异常处理机制 Go语言引...

  • 2021-06-08

    Go的编程模式,错误处理 引入了其他语言的错误处理模式,最后,说明Go错误处理的好处。主要是将函数的入参、出参、错...

  • Go中有效的错误处理

    原文链接:https://morsmachine.dk/error-handling翻译:devabel 介绍 G...

  • 基础-3

    异常处理 error接口:Go中的一个关于错误处理的标准模式,属于Go内建的接口类型;type error int...

  • Go 并发编程:错误处理及错误传递

    一、协程错误管理 我们在基础系列讲过Go程序开发中的错误处理规范,展示了几种函数执行中的错误返回问题,而在Go并发...

  • Learn Golang in Days - Day 15-Go

    Learn Golang in Days - Day 15-Go错误处理 简介 Go语言通过内置错误接口提供了简单...

  • 9. Go错误类型及错误处理

    9. Go错误类型及错误处理 Go 错误是指程序执行过程中遇到与设计流程不相符的情况,引发的人为的或自动的反馈机制...

  • golang

    golang go和php的区别类型:go为编译性语言;php解释性语言错误:go的错误处理机制;php本身或者框...

  • Go 专栏|错误处理:defer,panic 和 recover

    原文链接: Go 专栏|错误处理:defer,panic 和 recover[https://mp.weixin....

  • Go开发关键技术指南:Errors

    Errors 错误处理是现实中经常碰到的、难以处理好的问题,下面会从下面几个方面探讨错误处理: 为什么Go没有选择...

网友评论

    本文标题:Go中有效的错误处理

    本文链接:https://www.haomeiwen.com/subject/kqiccftx.html