Golang Error and panic processing

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Error and Panic

Error: Predictable errors

Panic: Unforeseen anomalies

Panic processing

Handling Exceptions by Panic,defer,recover

The following example code, when an HTTP link to come, Golang will call the serve function, the serve function will parse the HTTP protocol, and then hand over to the upper handler processing, if the upper handler throws an exception, Will be captured by the recover function inside the defer to print out the current stack information so that an exception to an HTTP request causes the entire program to crash.

func (c *conn)serve() {    defer func() {        if err := recover(); err != nil {            const size = 64 << 10            buf := make([]byte, size)            buf = buf[:runtime.Stack(buf, false)]            fmt.Printlf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf)        }    }()    w := c.readRequest()    

Error handling

Centralized handling of errors in defer

func demo() {    var err error     defer func() {        if err != nil {            //  处理发生的错误,打印日志等信息            return         }    }    err = func1()    if err != nil {        return     }    err = func2()    if err != nil {        return     }    

all-or-nothing check

If there are multiple small tasks in a complete task, we do not need to perform each small task to check for errors, we can judge the execution of the whole task after all the small tasks are done.

//冗长的代码,满篇重复的 if err != nil _, err = fd.Write(p0[a:b])if err != nil {    return err}_, err = fd.Write(p1[c:d])if err != nil {    return err}_, err = fd.Write(p2[e:f])if err != nil {    return err}// and so on

We can simplify the code like this

type errWriter struct {    w   io.Writer    err error}func (ew *errWriter) write(buf []byte) {    if ew.err != nil {        return    }    _, ew.err = ew.w.Write(buf)}ew := &errWriter{w: fd}ew.write(p0[a:b])ew.write(p1[c:d])ew.write(p2[e:f])// 只需要在最后检查一次if ew.err != nil {    return ew.err}

One obvious problem with this approach is that we don't know if the whole task is going to be an error in the execution of a small task, which is not appropriate if we need to focus on the progress of each small task.

Error context

Error is an interface where any type that implements the error () function satisfies the interface, errors. New () actually returns a errorstring type that contains only a string string, with no contextual information about the error, and when we throw the error up, we do it uniformly at the top, You can only output a single string of information without knowing where the error occurred and under what circumstances.

type error interface {    Error() string}type errorString struct {    s string}func (e *errorString) Error() string {    return e.s}func New(text string) error {    return &errorString{text}}

Since error is an interface, we can also implement a type to satisfy the interface, and record the error file, function, stack and other information, more convenient to find the wrong.

Package Stackerrimport ("FMT" "Runtime" "strings") type Stackerr struct {Filename string callingmetho  D String Line int errormessage string StackTrace string}func New (Err interface{}) *stackerr {var Errmessage string switch T: = Err. (type)    {Case *stackerr:return t case string:errmessage = t case error:errmessage = T.error () Default:errmessage = FMT. Sprintf ("%v", T)} Stackerr: = &stackerr{} Stackerr.errormessage = Errmessage _, file, line, OK: = Runtime . Caller (1) If OK {stackerr.line = line components: = Strings.  Split (file, "/") Stackerr.filename = components[(len (components)-1)]} Const SIZE = 1 << buf: = Make ([]byte, size) N: = runtime. Stack (buf, false) Stackerr.stacktrace = string (Buf[:n]) return Stackerr}func (this *stackerr) Error () string {RE Turn this. Errormessage}func (This *stackerr) Stack () string {return FMT.sprintf ("{%s:%d}%s\nstack info:\n%s", this. Filename, this. Line, this. ErrorMessage, this. StackTrace)}func (this *stackerr) Detail () string {return FMT. Sprintf ("{%s:%d}%s", this.) Filename, this. Line, this. ErrorMessage)}

Third-party Error library recommendations

The github.com/pkg/errors is an error library that provides a log context wrapper that makes it easy to add additional information to the error, record stack information, and so on. Refer to GitHub or source code for detailed instructions.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.