<!-- Error Handling and Go -->

<p>
If you have written any Go code you have probably encountered the built-in
<code>error</code> type. Go code uses <code>error</code> values to
indicate an abnormal state. For example, the <code>os.Open</code> function
returns a non-nil <code>error</code> value when it fails to open a file.
</p>

<pre><!--{{code "progs/error.go" `/func Open/`}}
-->func Open(name string) (file *File, err error)
</pre>

<p>
The following code uses <code>os.Open</code> to open a file. If an error
occurs it calls <code>log.Fatal</code> to print the error message and stop.
</p>

<pre><!--{{code "progs/error.go" `/func openFile/` `/STOP/`}}
-->    f, err := os.Open(&#34;filename.ext&#34;)
    if err != nil {
        log.Fatal(err)
    }
    // do something with the open *File f
</pre>

<p>
You can get a lot done in Go knowing just this about the <code>error</code>
type, but in this article we'll take a closer look at <code>error</code> and
discuss some good practices for error handling in Go.
</p>

<p>
<b>The error type</b>
</p>

<p>
The <code>error</code> type is an interface type. An <code>error</code>
variable represents any value that can describe itself as a string. Here is the
interface's declaration:
</p>

<pre>type error interface {
    Error() string
}</pre>

<p>
The <code>error</code> type, as with all built in types, is
<a href="/doc/go_spec.html#Predeclared_identifiers">predeclared</a> in the
<a href="/doc/go_spec.html#Blocks">universe block</a>.
</p>

<p>
The most commonly-used <code>error</code> implementation is the
<a href="/pkg/errors/">errors</a> package's unexported <code>errorString</code> type.
</p>

<pre><!--{{code "progs/error.go" `/errorString/` `/STOP/`}}
-->// errorString is a trivial implementation of error.
type errorString struct {
    s string
}

func (e *errorString) Error() string {
    return e.s
}
</pre>

<p>
You can construct one of these values with the <code>errors.New</code>
function. It takes a string that it converts to an <code>errors.errorString</code>
and returns as an <code>error</code> value.
</p>

<pre><!--{{code "progs/error.go" `/New/` `/STOP/`}}
-->// New returns an error that formats as the given text.
func New(text string) error {
    return &amp;errorString{text}
}
</pre>

<p>
Here's how you might use <code>errors.New</code>:
</p>

<pre><!--{{code "progs/error.go" `/func Sqrt/` `/STOP/`}}
-->func Sqrt(f float64) (float64, error) {
    if f &lt; 0 {
        return 0, errors.New(&#34;math: square root of negative number&#34;)
    }
    // implementation
}
</pre>

<p>
A caller passing a negative argument to <code>Sqrt</code> receives a non-nil
<code>error</code> value (whose concrete representation is an
<code>errors.errorString</code> value). The caller can access the error string
("math: square root of...") by calling the <code>error</code>'s
<code>Error</code> method, or by just printing it:
</p>

<pre><!--{{code "progs/error.go" `/func printErr/` `/STOP/`}}
-->    f, err := Sqrt(-1)
    if err != nil {
        fmt.Println(err)
    }
</pre>

<p>
The <a href="/pkg/fmt/">fmt</a> package formats an <code>error</code> value
by calling its <code>Error() string</code> method.
</p>

<p>
It is the error implementation's responsibility to summarize the context.
The error returned by <code>os.Open</code> formats as "open /etc/passwd:
permission denied," not just "permission denied."  The error returned by our
<code>Sqrt</code> is missing information about the invalid argument.
</p>

<p>
To add that information, a useful function is the <code>fmt</code> package's
<code>Errorf</code>. It formats a string according to <code>Printf</code>'s
rules and returns it as an <code>error</code> created by
<code>errors.New</code>.
</p>

<pre><!--{{code "progs/error.go" `/fmtError/` `/STOP/`}}
-->    if f &lt; 0 {
        return 0, fmt.Errorf(&#34;math: square root of negative number %g&#34;, f)
    }
</pre>

<p>
In many cases <code>fmt.Errorf</code> is good enough, but since
<code>error</code> is an interface, you can use arbitrary data structures as
error values, to allow callers to inspect the details of the error.
</p>

<p>
For instance, our hypothetical callers might want to recover the invalid
argument passed to <code>Sqrt</code>. We can enable that by defining a new
error implementation instead of using <code>errors.errorString</code>:
</p>

<pre><!--{{code "progs/error.go" `/type NegativeSqrtError/` `/STOP/`}}
-->type NegativeSqrtError float64

func (f NegativeSqrtError) Error() string {
    return fmt.Sprintf(&#34;math: square root of negative number %g&#34;, float64(f))
}
</pre>

<p>
A sophisticated caller can then use a
<a href="/doc/go_spec.html#Type_assertions">type assertion</a> to check for a
<code>NegativeSqrtError</code> and handle it specially, while callers that just
pass the error to <code>fmt.Println</code> or <code>log.Fatal</code> will see
no change in behavior.
</p>

<p>
As another example, the <a href="/pkg/encoding/json/">json</a> package specifies a
<code>SyntaxError</code> type that the <code>json.Decode</code> function
returns when it encounters a syntax error parsing a JSON blob.
</p>

<pre><!--{{code "progs/error.go" `/type SyntaxError/` `/STOP/`}}
-->type SyntaxError struct {
    msg    string // description of error
    Offset int64  // error occurred after reading Offset bytes
}

func (e *SyntaxError) Error() string { return e.msg }
</pre>

<p>
The <code>Offset</code> field isn't even shown in the default formatting of the
error, but callers can use it to add file and line information to their error
messages:
</p>

<pre><!--{{code "progs/error.go" `/func decodeError/` `/STOP/`}}
-->    if err := dec.Decode(&amp;val); err != nil {
        if serr, ok := err.(*json.SyntaxError); ok {
            line, col := findLine(f, serr.Offset)
            return fmt.Errorf(&#34;%s:%d:%d: %v&#34;, f.Name(), line, col, err)
        }
        return err
    }
</pre>

<p>
(This is a slightly simplified version of some
<a href="http://camlistore.org/code/?p=camlistore.git;a=blob;f=lib/go/camli/jsonconfig/eval.go#l68">actual code</a>
from the <a href="http://camlistore.org">Camlistore</a> project.)
</p>

<p>
The <code>error</code> interface requires only a <code>Error</code> method;
specific error implementations might have additional methods. For instance, the
<a href="/pkg/net/">net</a> package returns errors of type
<code>error</code>, following the usual convention, but some of the error
implementations have additional methods defined by the <code>net.Error</code>
interface:
</p>

<pre>package net

type Error interface {
    error
    Timeout() bool   // Is the error a timeout?
    Temporary() bool // Is the error temporary?
}</pre>

<p>
Client code can test for a <code>net.Error</code> with a type assertion and
then distinguish transient network errors from permanent ones. For instance, a
web crawler might sleep and retry when it encounters a temporary error and give
up otherwise.
</p>

<pre><!--{{code "progs/error.go" `/func netError/` `/STOP/`}}
-->        if nerr, ok := err.(net.Error); ok &amp;&amp; nerr.Temporary() {
            time.Sleep(1e9)
            continue
        }
        if err != nil {
            log.Fatal(err)
        }
</pre>

<p>
<b>Simplifying repetitive error handling</b>
</p>

<p>
In Go, error handling is important. The language's design and conventions
encourage you to explicitly check for errors where they occur (as distinct from
the convention in other languages of throwing exceptions and sometimes catching
them). In some cases this makes Go code verbose, but fortunately there are some
techniques you can use to minimize repetitive error handling.
</p>

<p>
Consider an <a href="http://code.google.com/appengine/docs/go/">App Engine</a>
application with an HTTP handler that retrieves a record from the datastore and
formats it with a template.
</p>

<pre><!--{{code "progs/error2.go" `/func init/` `/STOP/`}}
-->func init() {
    http.HandleFunc(&#34;/view&#34;, viewRecord)
}

func viewRecord(w http.ResponseWriter, r *http.Request) {
    c := appengine.NewContext(r)
    key := datastore.NewKey(c, &#34;Record&#34;, r.FormValue(&#34;id&#34;), 0, nil)
    record := new(Record)
    if err := datastore.Get(c, key, record); err != nil {
        http.Error(w, err.Error(), 500)
        return
    }
    if err := viewTemplate.Execute(w, record); err != nil {
        http.Error(w, err.Error(), 500)
    }
}
</pre>

<p>
This function handles errors returned by the <code>datastore.Get</code>
function and <code>viewTemplate</code>'s <code>Execute</code> method. In both
cases, it presents a simple error message to the user with the HTTP status code
500 ("Internal Server Error"). This looks like a manageable amount of code, but
add some more HTTP handlers and you quickly end up with many copies of
identical error handling code.
</p>

<p>
To reduce the repetition we can define our own HTTP <code>appHandler</code>
type that includes an <code>error</code> return value:
</p>

<pre><!--{{code "progs/error3.go" `/type appHandler/`}}
-->type appHandler func(http.ResponseWriter, *http.Request) error
</pre>

<p>
Then we can change our <code>viewRecord</code> function to return errors:
</p>

<pre><!--{{code "progs/error3.go" `/func viewRecord/` `/STOP/`}}
-->func viewRecord(w http.ResponseWriter, r *http.Request) error {
    c := appengine.NewContext(r)
    key := datastore.NewKey(c, &#34;Record&#34;, r.FormValue(&#34;id&#34;), 0, nil)
    record := new(Record)
    if err := datastore.Get(c, key, record); err != nil {
        return err
    }
    return viewTemplate.Execute(w, record)
}
</pre>

<p>
This is simpler than the original version, but the <a
href="/pkg/net/http/">http</a> package doesn't understand functions that return
<code>error</code>.
To fix this we can implement the <code>http.Handler</code> interface's
<code>ServeHTTP</code> method on <code>appHandler</code>:
</p>

<pre><!--{{code "progs/error3.go" `/ServeHTTP/` `/STOP/`}}
-->func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if err := fn(w, r); err != nil {
        http.Error(w, err.Error(), 500)
    }
}
</pre>

<p>
The <code>ServeHTTP</code> method calls the <code>appHandler</code> function
and displays the returned error (if any) to the user.  Notice that the method's
receiver, <code>fn</code>, is a function. (Go can do that!) The method invokes
the function by calling the receiver in the expression <code>fn(w, r)</code>.
</p>

<p>
Now when registering <code>viewRecord</code> with the http package we use the
<code>Handle</code> function (instead of <code>HandleFunc</code>) as
<code>appHandler</code> is an <code>http.Handler</code> (not an
<code>http.HandlerFunc</code>). 
</p>

<pre><!--{{code "progs/error3.go" `/func init/` `/STOP/`}}
-->func init() {
    http.Handle(&#34;/view&#34;, appHandler(viewRecord))
}
</pre>

<p>
With this basic error handling infrastructure in place, we can make it more
user friendly. Rather than just displaying the error string, it would be better
to give the user a simple error message with an appropriate HTTP status code,
while logging the full error to the App Engine developer console for debugging
purposes.
</p>

<p>
To do this we create an <code>appError</code> struct containing an
<code>error</code> and some other fields:
</p>

<pre><!--{{code "progs/error4.go" `/type appError/` `/STOP/`}}
-->type appError struct {
    Error   error
    Message string
    Code    int
}
</pre>

<p>
Next we modify the appHandler type to return <code>*appError</code> values:
</p>

<pre><!--{{code "progs/error4.go" `/type appHandler/`}}
-->type appHandler func(http.ResponseWriter, *http.Request) *appError
</pre>

<p>
(It's usually a mistake to pass back the concrete type of an error rather than
<code>error</code>, for reasons to be discussed in another article, but
it's the right thing to do here because <code>ServeHTTP</code> is the only
place that sees the value and uses its contents.)
</p>

<p>
And make <code>appHandler</code>'s <code>ServeHTTP</code> method display the
<code>appError</code>'s <code>Message</code> to the user with the correct HTTP
status <code>Code</code> and log the full <code>Error</code> to the developer
console:
</p>

<pre><!--{{code "progs/error4.go" `/ServeHTTP/` `/STOP/`}}
-->func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if e := fn(w, r); e != nil { // e is *appError, not os.Error.
        c := appengine.NewContext(r)
        c.Errorf(&#34;%v&#34;, e.Error)
        http.Error(w, e.Message, e.Code)
    }
}
</pre>

<p>
Finally, we update <code>viewRecord</code> to the new function signature and
have it return more context when it encounters an error: 
</p>

<pre><!--{{code "progs/error4.go" `/func viewRecord/` `/STOP/`}}
-->func viewRecord(w http.ResponseWriter, r *http.Request) *appError {
    c := appengine.NewContext(r)
    key := datastore.NewKey(c, &#34;Record&#34;, r.FormValue(&#34;id&#34;), 0, nil)
    record := new(Record)
    if err := datastore.Get(c, key, record); err != nil {
        return &amp;appError{err, &#34;Record not found&#34;, 404}
    }
    if err := viewTemplate.Execute(w, record); err != nil {
        return &amp;appError{err, &#34;Can&#39;t display record&#34;, 500}
    }
    return nil
}
</pre>

<p>
This version of <code>viewRecord</code> is the same length as the original, but
now each of those lines has specific meaning and we are providing a friendlier
user experience.
</p>

<p>
It doesn't end there; we can further improve the error handling in our
application. Some ideas:
</p>

<ul>
<li>give the error handler a pretty HTML template,
<li>make debugging easier by writing the stack trace to the HTTP response when
the user is an administrator,
<li>write a constructor function for <code>appError</code> that stores the
stack trace for easier debugging, 
<li>recover from panics inside the <code>appHandler</code>, logging the error
to the console as "Critical," while simply telling the user "a serious error
has occurred." This is a nice touch to avoid exposing the user to inscrutable
error messages caused by programming errors.
See the <a href="defer_panic_recover.html">Defer, Panic, and Recover</a>
article for more details.
</ul>

<p>
<b>Conclusion</b>
</p>

<p>
Proper error handling is an essential requirement of good software. By
employing the techniques described in this post you should be able to write
more reliable and succinct Go code.
</p>
