# Error Handling — Problem Overview

Russ Cox\
August 27, 2018

## Introduction

This overview and the accompanying
[detailed draft design](go2draft-error-handling.md)
are part of a collection of [Go 2 draft design documents](go2draft.md).
The overall goal of the Go 2 effort is to address
the most significant ways that Go fails to scale
to large code bases and large developer efforts.

One way that Go programs fail to scale well is in the
writing of error-checking and error-handling code.
In general Go programs have too much code checking errors
and not enough code handling them.
(This will be illustrated below.)
The draft design aims to address this problem by introducing
lighter-weight syntax for error checks
than the current idiomatic assignment-and-if-statement combination.

As part of Go 2, we are also considering, as a separate concern,
changes to the [semantics of error values](go2draft-error-values-overview.md),
but this document is only about error checking and handling.

## Problem

To scale to large code bases, Go programs must be lightweight,
[without undue repetition](https://www.youtube.com/watch?v=5kj5ApnhPAE),
and also robust,
[dealing gracefully with errors](https://www.youtube.com/watch?v=lsBF58Q-DnY)
when they do arise.

In the design of Go, we made a conscious choice
to use explicit error results and explicit error checks.
In contrast, C most typically uses explicit checking
of an implicit error result, [errno](http://man7.org/linux/man-pages/man3/errno.3.html),
while exception handling—found in many languages,
including C++, C#, Java, and Python—represents implicit checking of implicit results.

The subtleties of implicit checking are covered well in
Raymond Chen’s pair of blog posts,
"[Cleaner, more elegant, and wrong](https://devblogs.microsoft.com/oldnewthing/20040422-00/?p=39683)" (2004),
and "[Cleaner, more elegant, and harder to recognize](https://devblogs.microsoft.com/oldnewthing/20050114-00/?p=36693)" (2005).
In essence, because you can’t see implicit checks at all,
it is very hard to verify by inspection that the error handling code
correctly recovers from the state of the program at the time the check fails.

For example, consider this code, written in a hypothetical dialect of Go with exceptions:

	func CopyFile(src, dst string) throws error {
		r := os.Open(src)
		defer r.Close()

		w := os.Create(dst)
		io.Copy(w, r)
		w.Close()
	}

It is nice, clean, elegant code.
It is also invisibly wrong: if `io.Copy` or `w.Close` fails,
the code does not remove the partially-written `dst` file.

On the other hand, the equivalent actual Go code today would be:

	func CopyFile(src, dst string) error {
		r, err := os.Open(src)
		if err != nil {
			return err
		}
		defer r.Close()

		w, err := os.Create(dst)
		if err != nil {
			return err
		}
		defer w.Close()

		if _, err := io.Copy(w, r); err != nil {
			return err
		}
		if err := w.Close(); err != nil {
			return err
		}
	}

This code is not nice, not clean, not elegant, and still wrong:
like the previous version, it does not remove `dst` when `io.Copy` or `w.Close` fails.
There is a plausible argument that at least a visible check
could prompt an attentive reader to wonder about
the appropriate error-handling response at that point in the code.
In practice, however, error checks take up so much space
that readers quickly learn to skip them to see the structure of the code.

This code also has a second omission in its error handling.
Functions should typically [include relevant information](https://golang.org/doc/effective_go.html#errors)
about their arguments in their errors,
like `os.Open` returning the name of the file being opened.
Returning the error unmodified produces a failure
without any information about the sequence of operations that led to the error.

In short, this Go code has too much error checking
and not enough error handling.
A more robust version with more helpful errors would be:


	func CopyFile(src, dst string) error {
		r, err := os.Open(src)
		if err != nil {
			return fmt.Errorf("copy %s %s: %v", src, dst, err)
		}
		defer r.Close()

		w, err := os.Create(dst)
		if err != nil {
			return fmt.Errorf("copy %s %s: %v", src, dst, err)
		}

		if _, err := io.Copy(w, r); err != nil {
			w.Close()
			os.Remove(dst)
			return fmt.Errorf("copy %s %s: %v", src, dst, err)
		}

		if err := w.Close(); err != nil {
			os.Remove(dst)
			return fmt.Errorf("copy %s %s: %v", src, dst, err)
		}
	}

Correcting these faults has only made the code more correct, not cleaner or more elegant.

## Goals

For Go 2, we would like to make error checks more lightweight,
reducing the amount of Go program text dedicated to error checking.
We also want to make it more convenient to write error handling,
raising the likelihood that programmers will take the time to do it.

Both error checks and error handling must remain explicit,
meaning visible in the program text.
We do not want to repeat the pitfalls of exception handling.

Existing code must keep working and remain as valid as it is today.
Any changes must interoperate with existing code.

As mentioned above, it is not a goal of this draft design
to change or augment the semantics of errors.
For that discussion see the [error values problem overview](go2draft-error-values-overview.md).

## Draft Design

This section quickly summarizes the draft design,
as a basis for high-level discussion and comparison with other approaches.

The draft design introduces two new syntactic forms.
First, it introduces a checked expression `check f(x, y, z)` or `check err`,
marking an explicit error check.
Second, it introduces a `handle` statement defining an error handler.
When an error check fails, it transfers control to the innermost handler,
which transfers control to the next handler above it,
and so on, until a handler executes a `return` statement.

For example, the corrected code above shortens to:

	func CopyFile(src, dst string) error {
		handle err {
			return fmt.Errorf("copy %s %s: %v", src, dst, err)
		}

		r := check os.Open(src)
		defer r.Close()

		w := check os.Create(dst)
		handle err {
			w.Close()
			os.Remove(dst) // (only if a check fails)
		}

		check io.Copy(w, r)
		check w.Close()
		return nil
	}

The `check`/`handle` combination is permitted in functions
that do not themselves return errors.
For example, here is a main function from a
[useful but trivial program](https://github.com/rsc/tmp/blob/master/unhex/main.go):

	func main() {
		hex, err := ioutil.ReadAll(os.Stdin)
		if err != nil {
			log.Fatal(err)
		}

		data, err := parseHexdump(string(hex))
		if err != nil {
			log.Fatal(err)
		}

		os.Stdout.Write(data)
	}

It would be shorter and clearer to write instead:

	func main() {
		handle err {
			log.Fatal(err)
		}

		hex := check ioutil.ReadAll(os.Stdin)
		data := check parseHexdump(string(hex))
		os.Stdout.Write(data)
	}

For details, see the [draft design](go2draft-error-handling.md).

## Discussion and Open Questions

These draft designs are meant only as a starting point for community discussion.
We fully expect the details to be revised based on feedback and especially experience reports.
This section outlines some of the questions that remain to be answered.

**Check versus try**.
The keyword `check` is a clear statement of what is being done.
Originally we used the well-known exception keyword `try`.
This did read well for function calls:

	data := try parseHexdump(string(hex))

But it did not read well for checks applied to error values:

	data, err := parseHexdump(string(hex))
	if err == ErrBadHex {
		... special handling ...
	}
	try err

In this case, `check err` is a clearer description than `try err`.
Rust originally used `try!` to mark an explicit error check
but moved to a special `?` operator instead.
Swift also uses `try` to mark an explicit error check,
but also `try!` and `try?`, and as part of a broader
analogy to exception-handling that also includes `throw` and `catch`.

Overall it seems that the draft design’s `check`/`handle`
are sufficiently different from exception handling
and from Rust and Swift to justify the clearer keyword,
`check`, over the more familiar one, `try`.

Both Rust and Swift are discussed in more detail below.

**Defer**.
The error handling is in some ways similar to [`defer`](https://golang.org/ref/spec#Defer_statements) and
[`recover`](https://golang.org/ref/spec#Handling_panics),
but for errors instead of panics.
The current draft design makes error handlers chain lexically,
while `defer` builds up a chain at runtime
depending on what code executes.
This difference matters for handlers (or deferred functions)
declared in conditional bodies and loops.
Although lexical stacking of error handlers seems like a marginally better design,
it may be less surprising to match `defer` exactly.
As an example where `defer`-like handling would be more convenient,
if `CopyFile` established its destination `w` as either `os.Stdout` or the result of `os.Create`,
then it would be helpful to be able to introduce the `os.Remove(dst)` handler conditionally.

**Panics**.
We’ve spent a while trying to harmonize error handling and panics,
so that cleanup due to error handling need not be repeated for cleanup due to panics.
All our attempts at unifying the two only led to more complexity.

**Feedback**.
The most useful general feedback would be examples of interesting uses
that are enabled or disallowed by the draft design.
We’d also welcome feedback about the points above,
especially based on experience with complex
or buggy error handling in real programs.

We are collecting links to feedback at
[golang.org/wiki/Go2ErrorHandlingFeedback](https://golang.org/wiki/Go2ErrorHandlingFeedback).

## Designs in Other Languages

The problem section above briefly discussed C and exception-based languages.

Other recent language designs have also recognized
the problems caused by exception handling’s invisible error checks,
and those designs are worth examining in more detail.
The Go draft design was inspired, at least in part, by each of them.

## Rust

Like Go, [Rust distinguishes](https://doc.rust-lang.org/book/second-edition/ch09-00-error-handling.html)
between expected errors, like "file not found", and unexpected errors,
like accessing past the end of an array.
Expected errors are returned explicitly
while unexpected errors become program-ending panics.
But Rust has little special-purpose
language support for expected errors.
Instead, concise handling of expected errors
is done almost entirely by generics.

In Rust, functions return single values (possibly a single tuple value),
and a function returning a potential error returns a
[discriminated union `Result<T, E>`](https://doc.rust-lang.org/book/second-edition/ch09-02-recoverable-errors-with-result.html)
that is either the successful result of type `T` or an error of type `E`.

	enum Result<T, E> {
		Ok(T),
		Err(E),
	}

For example, `fs::File::Open` returns a `Result<fs::File, io::Error>`.
The generic `Result<T, E>` type defines an
[unwrap method](https://doc.rust-lang.org/book/second-edition/ch09-02-recoverable-errors-with-result.html#shortcuts-for-panic-on-error-unwrap-and-expect)
that turns a result into the underlying value (of type `T`)
or else panics (if the result represents an error).

If code does want to check an error instead of panicking,
[the `?` operator](https://doc.rust-lang.org/book/second-edition/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator)
macro-expands `use(result?)` into the Rust equivalent of this Go code:

	if result.err != nil {
		return result.err
	}
	use(result.value)


The `?` operator therefore helps shorten the error checking
and is very similar to the draft design’s `check`.
But Rust has no equivalent of `handle`:
the convenience of the `?` operator comes with
the likely omission of proper handling.
Rust’s equivalent of Go’s explicit error check `if err != nil` is
[using a `match` statement](https://doc.rust-lang.org/book/second-edition/ch09-02-recoverable-errors-with-result.html),
which is equally verbose.

Rust’s `?` operator began life as
[the `try!` macro](https://doc.rust-lang.org/beta/book/first-edition/error-handling.html#the-real-try-macro).

## Swift

Swift’s `try`, `catch`, and `throw` keywords appear at first glance to be
implementing exception handling, but really they are syntax for explicit error handling.

Each function’s signature specifies whether the function
can result in ("throw") an error.
Here is an [example from the Swift book](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html#ID510):

	func canThrowErrors() throws -> String
	func cannotThrowErrors() -> String

These are analogous to the Go result lists `(string, error)` and `string`.

Inside a "throws" function, the
`throw` statement returns an error,
as in this [example, again from the Swift book](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html#ID509):

	throw VendingMachineError.insufficientFunds(coinsNeeded: 5)

Every call to a "throws" function must specify at the call site
what to do in case of error. In general that means nesting the call
(perhaps along with other calls) inside a [do-catch block](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html#ID541),
with all potentially-throwing calls marked by the `try` keyword:


	do {
		let s = try canThrowErrors()
		let t = cannotThrowErrors()
		let u = try canThrowErrors() // a second call
	} catch {
		handle error from try above
	}

The key differences from exception handling as in C++, Java, Python,
and similar languages are:

- Every error check is marked.
- There must be a `catch` or other direction about what to do with an error.
- There is no implicit stack unwinding.

Combined, those differences make all error checking,
handling, and control flow transfers explicit, as in Go.

Swift introduces three shorthands to avoid having
to wrap every throwing function call in a `do`-`catch` block.

First, outside a block, `try canThrowErrors()`
[checks for the error and re-throws it](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html#ID510),
like Rust’s old `try!` macro and current `?` operator.

Second, `try! canThrowErrors()`
[checks for the error and turns it into a runtime assertion failure](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html#ID513),
like Rust’s `.unwrap` method.

Third, `try? canThrowErrors()`
[evaluates to nil on error, or else the function’s result](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html#ID542).
The Swift book gives this example:

	func fetchData() -> Data? {
		if let data = try? fetchDataFromDisk() { return data }
		if let data = try? fetchDataFromServer() { return data }
		return nil
	}

The example discards the exact reasons these functions failed.

For cleanup, Swift adds lexical [`defer` blocks](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html#ID514),
which run when the enclosing scope is exited, whether by an explicit `return` or by throwing an error.
