<!--{
	"Title": "Error Handling and Go"
}-->
<!--
  DO NOT EDIT: created by
    tmpltohtml articles/error_handling.tmpl
-->

<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 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>
