golang Error Handling

1. Error

Wrong with built-in error types to represent.

type error interface {  
    Error() string
}

error With a signature for the  Error() string method. All types implement this interface can be used as a type of error. Error()The method gives a description of the error.

package main
import (
        "fmt"
        "os"
)

func main(){
        f, err := os.Open("/test.txt")
        if err != nil {
                fmt.Println(err)
                return
        }
        fmt.Println(f.Name(), "opened successfully")
}
output:
open /test.txt: no such file or directory

fmt.Println When printing error, it internally calls the  Error() string method to get a description of the error.

Although the acquired file path error, but this method is very elegant. With the language version of the update, this description of the error are likely to change at any time, so that our program error .

1) asserts substructure type, field structure used for more information

Open function can be seen by reading the document, the wrong type of return is * PathError.

type PathError struct {  
    Op   string
    Path string
    Err  error
}

func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() }

* PathError type may be asserted by, for detailed field contents structure:

err is the interface variables, err (* os.PathError) type assertion err * os.PathError, so as to obtain the bottom of the interface, i.e., * PathError.

    f, err := os.Open("/test.txt")
    if err, ok := err.(*os.PathError); ok {
        fmt.Println("File at path", err.Path, "failed to open")
        return
    }

2) asserts the underlying structure type, method structures call for more information

3) direct comparison

Filepath package ErrBadPattern defined as follows:

var ErrBadPattern = errors.New("syntax error in pattern")

Direct comparison of the types of errors

    files, error := filepath.Glob("[")
    if error != nil && error == filepath.ErrBadPattern {
        fmt.Println(error)
        return
    }

2. Custom Error

Creating custom error easiest way is to use the  errors package  New functions.

package errors

// New returns an error that formats as the given text.
func New(text string) error {
    return &errorString{text}
}

// errorString is a trivial implementation of error.
type errorString struct {
    s string
}

func (e *errorString) Error() string {
    return e.s
}

Application errors.New in the function ():

func circleArea(radius float64) (float64, error) {  
    if radius < 0 {
        return 0, errors.New("Area calculation failed, radius is less than zero")
    }
    return math.Pi * radius * radius, nil
}

fmt.Errorf () to print error message

    if radius < 0 {
        return 0, fmt.Errorf("Area calculation failed, radius %0.2f is less than zero", radius)
    }

For more information on using a structure and provide the error field

Pointer receiver  *areaError, implements  error the interface  Error() string method.

type areaError struct {  
    err    string
    radius float64
}

func (e *areaError) Error() string {  
    return fmt.Sprintf("radius %0.2f: %s", e.radius, e.err)
}

    if radius < 0 {
        return 0, &areaError{"radius is negative", radius}
    }

For more information on the type of structure using the method to provide error

type areaError struct {  
    err    string //error description
    length float64 //length which caused the error
    width  float64 //width which caused the error
}
func (e *areaError) Error() string {  
    return e.err
}

func (e *areaError) lengthNegative() bool {  
    return e.length < 0
}

func (e *areaError) widthNegative() bool {  
    return e.width < 0
}
func rectArea(length, width float64) (float64, error) {  
    err := ""
    if length < 0 {
        err += "length is less than zero"
    }
    if width < 0 {
        if err == "" {
            err = "width is less than zero"
        } else {
            err += ", width is less than zero"
        }
    }
    if err != "" {
        return 0, &areaError{err, length, width}
    }
    return length * width, nil
}

3.panic

When the function occurs panic, it will terminate the operation, finishing the execution of all the delay after the function, program control returns to the caller of the function. The process would continue, until the current coroutine all functions return to exit, then the program will print out panic information, then print out a stack trace (Stack Trace), and finally the program terminates.

Note that you should use as much as possible error , instead of panic and recover. Only when the program can not continue to run, you should use the panic and recover mechanism.

panic There are two reasonable use cases.

  • l can not mistake a recovery will occur when the program can not continue to run. One example is the web server port can not be required binding. In this case, you should use panic, because if you can not bind to port, but also what not to do.
  • l on a programming error has occurred. If we have a method of receiving a pointer parameter, while others use it as an argument to call nil. In this case, we can use the panic, because this is a programming error: nil parameters using a method called only receive legitimate pointer.
func panic(interface{})

recover A built-in function is used to regain control panic coroutine.

func recover() interface{}

Only internal delay function call  recover to be useful. During the delay the function call  recover, you can take the  panic error message, and stop panic renewal event (Panicking Sequence), running back to normal. If you call in an external delay function  recover, you can not stop the panic renewal event.

Only in the same  Go coroutine call to recover in just works. recover You can not restore a different coroutine of panic.

 

Reference: Go series of tutorials - 32. panic and recover

Guess you like

Origin www.cnblogs.com/embedded-linux/p/11128958.html