blob: a08b7bd32d11772016c3001a989596415b75f7fd [file] [log] [blame] [view]
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11001# Errors
2
Dave Day0d6986a2014-12-10 15:02:18 +11003Errors are indicated by returning an `error` as an additional return value from a function. A `nil` value means that there was no error.
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11004
Dave Day0d6986a2014-12-10 15:02:18 +11005` error `s can be turned into strings by calling `Error`, their only method. You can create an error from a string by calling `errors.New`:
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11006
7```
8if failure {
Dave Day0d6986a2014-12-10 15:02:18 +11009 return errors.New("inverse tachyon pulse failed")
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110010}
11```
12
13Error strings should not start with a capital letter because they'll often be prefixed before printing:
14
15```
16err := TryInverseTachyonPulse()
17if err != nil {
Dave Day0d6986a2014-12-10 15:02:18 +110018 fmt.Printf("failed to solve problem: %s\n", err)
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110019}
20```
21
22If you expect calling code to be able to handle an error, you can distinguish classes of errors either by returning special values, or new types. You only need to distinguish differences that the calling code could be expected to handle in this way as the string allows one to communicate the details of the error.
23
Dave Day0d6986a2014-12-10 15:02:18 +110024`io.EOF` is a special value that signals the end of a stream. You can compare error values directly against io.EOF.
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110025
26If you want to carry extra data with the error, you can use a new type:
27
28```
29type ParseError struct {
Dave Day0d6986a2014-12-10 15:02:18 +110030 Line, Col int
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110031}
32
33func (p ParseError) Error() string {
Dave Day0d6986a2014-12-10 15:02:18 +110034 return fmt.Sprintf("parse error on line %d, column %d", p.Line, p.Col)
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110035}
36```
37
Dave Day0d6986a2014-12-10 15:02:18 +110038Calling code would test for a special type of `error` by using a type switch:
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110039
40```
41switch err := err.(type) {
42case ParseError:
Dave Day0d6986a2014-12-10 15:02:18 +110043 PrintParseError(err)
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110044}
45```
46
47## Naming
48
Dave Day0d6986a2014-12-10 15:02:18 +110049Error types end in `"Error"` and error variables start with `"Err"`:
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110050
51```
52package somepkg
53
54// ParseError is type of error returned when there's a parsing problem.
55type ParseError struct {
56 Line, Col int
57}
58
59var ErrBadAction = errors.New("somepkg: a bad action was performed")
60
61// -----
62
63package foo
64
65func foo() {
66 res, err := somepkgAction()
67 if err != nil {
68 if err == somepkg.ErrBadAction {
69 }
70 if pe, ok := err.(*somepkg.ParseError); ok {
71 line, col := pe.Line, pe.Col
72 // ....
73 }
74 }
75}
76```
77
78## References
79
80 * Errors (specification): http://golang.org/ref/spec#Errors
Dave Day0d6986a2014-12-10 15:02:18 +110081 * Package `errors`: http://golang.org/pkg/errors/
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110082 * Type switches: http://golang.org/doc/go_spec.html#TypeSwitchStmt