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.