aboutsummaryrefslogtreecommitdiff
path: root/content/go1.13-errors.article
diff options
context:
space:
mode:
Diffstat (limited to 'content/go1.13-errors.article')
-rw-r--r--content/go1.13-errors.article41
1 files changed, 21 insertions, 20 deletions
diff --git a/content/go1.13-errors.article b/content/go1.13-errors.article
index a3aa755..9935d06 100644
--- a/content/go1.13-errors.article
+++ b/content/go1.13-errors.article
@@ -1,12 +1,13 @@
-Working with Errors in Go 1.13
+# Working with Errors in Go 1.13
17 Oct 2019
Tags: errors, technical
+Summary: Go’s treatment of [errors as values](https://blog.golang.org/errors-are-values) has served us well over the last decade. Although the standard library’s support for errors has been minimal—just the `errors.New` and `fmt.Errorf` functions, which produce errors that contain only a message—the built-in `error` interface allows Go programmers to add whatever information they desire. All it requires is a type that implements an `Error` method:
Damien Neil and Jonathan Amsterdam
-* Introduction
+## Introduction
-Go’s treatment of [[https://blog.golang.org/errors-are-values][errors as values]]
+Go’s treatment of [errors as values](https://blog.golang.org/errors-are-values)
has served us well over the last decade. Although the standard library’s support
for errors has been minimal—just the `errors.New` and `fmt.Errorf` functions,
which produce errors that contain only a message—the built-in `error` interface
@@ -25,7 +26,7 @@ widely, from timestamps to filenames to server addresses. Often, that
information includes another, lower-level error to provide additional context.
The pattern of one error containing another is so pervasive in Go code that,
-after [[https://golang.org/issue/29934][extensive discussion]], Go 1.13 added
+after [extensive discussion](https://golang.org/issue/29934), Go 1.13 added
explicit support for it. This post describes the additions to the standard
library that provide that support: three new functions in the `errors` package,
and a new formatting verb for `fmt.Errorf`.
@@ -33,9 +34,9 @@ and a new formatting verb for `fmt.Errorf`.
Before describing the changes in detail, let's review how errors are examined
and constructed in previous versions of the language.
-* Errors before Go 1.13
+## Errors before Go 1.13
-** Examining errors
+### Examining errors
Go errors are values. Programs make decisions based on those values in a few
ways. The most common is to compare an error to `nil` to see if an operation
@@ -67,7 +68,7 @@ value as a more specific type.
// e.Name wasn't found
}
-** Adding information
+### Adding information
Frequently a function passes an error up the call stack while adding information
to it, like a brief description of what was happening when the error occurred. A
@@ -98,9 +99,9 @@ error.
The `os.PathError` type in the standard library is another example of one error which contains another.
-* Errors in Go 1.13
+## Errors in Go 1.13
-** The Unwrap method
+### The Unwrap method
Go 1.13 introduces new features to the `errors` and `fmt` standard library
packages to simplify working with errors that contain other errors. The most
@@ -115,9 +116,9 @@ method that returns its contained error:
func (e *QueryError) Unwrap() error { return e.Err }
The result of unwrapping an error may itself have an `Unwrap` method; we call
-the sequence of errors produced by repeated unwrapping the _error_chain_.
+the sequence of errors produced by repeated unwrapping the _error chain_.
-** Examining errors with Is and As
+### Examining errors with Is and As
The Go 1.13 `errors` package includes two new functions for examining errors: `Is` and `As`.
@@ -159,7 +160,7 @@ result of calling an error's `Unwrap` method, or `nil` when the error has no
`Unwrap` method. It is usually better to use `errors.Is` or `errors.As`,
however, since these functions will examine the entire chain in a single call.
-** Wrapping errors with %w
+### Wrapping errors with %w
As mentioned earlier, it is common to use the `fmt.Errorf` function to add additional information to an error.
@@ -183,7 +184,7 @@ Wrapping an error with `%w` makes it available to `errors.Is` and `errors.As`:
...
if errors.Is(err, ErrPermission) ...
-** Whether to Wrap
+### Whether to Wrap
When adding additional context to an error, either with `fmt.Errorf` or by
implementing a custom type, you need to decide whether the new error should wrap
@@ -204,9 +205,9 @@ database used by the function is an implementation detail, then exposing these
errors is a violation of abstraction. For example, if the `LookupUser` function
of your package `pkg` uses Go's `database/sql` package, then it may encounter a
`sql.ErrNoRows` error. If you return that error with
-`fmt.Errorf("accessing`DB:`%v",`err)`
+`fmt.Errorf("accessing DB: %v", err)`
then a caller cannot look inside to find the `sql.ErrNoRows`. But if
-the function instead returns `fmt.Errorf("accessing`DB:`%w",`err)`, then a
+the function instead returns `fmt.Errorf("accessing DB: %w", err)`, then a
caller could reasonably write
err := pkg.LookupUser(...)
@@ -224,7 +225,7 @@ either way; the choice to wrap is about whether to give _programs_ additional
information so they can make more informed decisions, or to withhold that
information to preserve an abstraction layer.
-* Customizing error tests with Is and As methods
+## Customizing error tests with Is and As methods
The `errors.Is` function examines each error in a chain for a match with a
target value. By default, an error matches the target if the two are equal. In
@@ -232,7 +233,7 @@ addition, an error in the chain may declare that it matches a target by
implementing an `Is` _method_.
As an example, consider this error inspired by the
-[[https://commandcenter.blogspot.com/2017/12/error-handling-in-upspin.html][Upspin error package]]
+[Upspin error package](https://commandcenter.blogspot.com/2017/12/error-handling-in-upspin.html)
which compares an error against a template, considering only fields which are
non-zero in the template:
@@ -256,7 +257,7 @@ non-zero in the template:
The `errors.As` function similarly consults an `As` method when present.
-* Errors and package APIs
+## Errors and package APIs
A package which returns errors (and most do) should describe what properties of
those errors programmers may rely on. A well-designed package will also avoid
@@ -326,7 +327,7 @@ do not return the underlying error directly.
// ...
}
-* Conclusion
+## Conclusion
Although the changes we’ve discussed amount to just three functions and a
formatting verb, we hope they will go a long way toward improving how errors are
@@ -334,6 +335,6 @@ handled in Go programs. We expect that wrapping to provide additional context
will become commonplace, helping programs to make better decisions and helping
programmers to find bugs more quickly.
-As Russ Cox said in his [[https://blog.golang.org/experiment][GopherCon 2019 keynote]],
+As Russ Cox said in his [GopherCon 2019 keynote](https://blog.golang.org/experiment),
on the path to Go 2 we experiment, simplify and ship. Now that we’ve
shipped these changes, we look forward to the experiments that will follow.