Errors are indicated by returning an error
as an additional return value from a function. A nil
value means that there was no error.
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
:
if failure {
return errors.New("inverse tachyon pulse failed")
}
Error strings should not start with a capital letter because they'll often be prefixed before printing:
err := TryInverseTachyonPulse()
if err != nil {
fmt.Printf("failed to solve problem: %s\n", err)
}
If 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.
io.EOF
is a special value that signals the end of a stream. You can compare error values directly against io.EOF.
If you want to carry extra data with the error, you can use a new type:
type ParseError struct {
Line, Col int
}
func (p ParseError) Error() string {
return fmt.Sprintf("parse error on line %d, column %d", p.Line, p.Col)
}
Calling code would test for a special type of error
by using a type switch:
switch err := err.(type) {
case ParseError:
PrintParseError(err)
}
Error types end in "Error"
and error variables start with "Err"
:
package somepkg
// ParseError is type of error returned when there's a parsing problem.
type ParseError struct {
Line, Col int
}
var ErrBadAction = errors.New("somepkg: a bad action was performed")
// -----
package foo
func foo() {
res, err := somepkgAction()
if err != nil {
if err == somepkg.ErrBadAction {
}
if pe, ok := err.(*somepkg.ParseError); ok {
line, col := pe.Line, pe.Col
// ....
}
}
}
- Errors (specification): http://golang.org/ref/spec#Errors
- Package
errors
: http://golang.org/pkg/errors/ - Type switches: http://golang.org/doc/go_spec.html#TypeSwitchStmt