diff --git a/content/go1.13-errors.article b/content/go1.13-errors.article
new file mode 100644
index 0000000..904b0eb
--- /dev/null
+++ b/content/go1.13-errors.article
@@ -0,0 +1,345 @@
+Working with Errors in Go 1.13
+17 Oct 2019
+Tags: errors, technical
+
+Damien Neil and Jonathan Amsterdam
+
+* Introduction
+
+Go’s treatment of [[https://blog.golang.org/errors-are-values][errors as 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:
+
+
+    type QueryError struct {
+        Query string
+        Err   error
+    }
+
+    func (e *QueryError) Error() string { return e.Query + ": " + e.Err.Error() }
+
+Error types like this one are ubiquitous, and the information they store varies
+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
+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`.
+
+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
+
+** 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
+failed.
+
+    if err != nil {
+        // something went wrong
+    }
+
+Sometimes we compare an error to a known _sentinel_ value, to see if a specific error has occurred.
+
+    var ErrNotFound = errors.New("not found")
+
+    if err == ErrNotFound {
+        // something wasn't found
+    }
+
+An error value may be of any type which satisfies the language-defined `error`
+interface. A program can use a type assertion or type switch to view an error
+value as a more specific type.
+
+    type NotFoundError struct {
+        Name string
+    }
+
+    func (e *NotFoundError) Error() string { return e.Name + ": not found" }
+
+    if e, ok := err.(*NotFoundError); ok {
+        // e.Name wasn't found
+    }
+
+
+** 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
+simple way to do this is to construct a new error that includes the text of the
+previous one:
+
+    if err != nil {
+        return fmt.Errorf("decompress %v: %v", name, err)
+    }
+
+Creating a new error with `fmt.Errorf` discards everything from the original
+error except the text. As we saw above with `QueryError`, we may sometimes want
+to define a new error type that contains the underlying error, preserving it for
+inspection by code. Here is `QueryError` again:
+
+
+    type QueryError struct {
+        Query string
+        Err   error
+    }
+
+Programs can look inside a `*QueryError` value to make decisions based on the
+underlying error. You'll sometimes see this referred to as "unwrapping" the
+error.
+
+    if e, ok := err.(*QueryError); ok && e.Err == ErrPermission {
+        // query failed because of a permission problem
+    }
+
+
+The `os.PathError` type in the standard library is another example of one error which contains another.
+
+* Errors in Go 1.13
+
+** 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
+significant of these is a convention rather than a change: an error which
+contains another may implement an `Unwrap` method returning the underlying
+error. If `e1.Unwrap()` returns `e2`, then we say that `e1` _wraps_ `e2`, and
+that you can _unwrap_ `e1` to get `e2`.
+
+Following this convention, we can give the `QueryError` type above an `Unwrap`
+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_.
+
+** Examining errors with Is and As
+
+The Go 1.13 `errors` package includes two new functions for examining errors: `Is` and `As`. 
+
+The `errors.Is` function compares an error to a value.
+
+    // Similar to:
+    //   if err == ErrNotFound { … }
+    if errors.Is(err, ErrNotFound) {
+        // something wasn't found
+    }
+
+The `As` function tests whether an error is a specific type.
+
+    // Similar to:
+    //   if e, ok := err.(*QueryError); ok { … }
+    var e *QueryError
+    if errors.As(err, &e) {
+        // err is a *QueryError, and e is set to the error's value
+    }
+
+In the simplest case, the `errors.Is` function behaves like a comparison to a
+sentinel error, and the `errors.As` function behaves like a type assertion. When
+operating on wrapped errors, however, these functions consider all the errors in
+a chain. Let's look again at the example from above of unwrapping a `QueryError`
+to examine the underlying error:
+
+    if e, ok := err.(*QueryError); ok && e.Err == ErrPermission {
+        // query failed because of a permission problem
+    }
+
+Using the `errors.Is` function, we can write this as:
+
+    if errors.Is(err, ErrPermission) {
+        // err, or some error that it wraps, is a permission problem
+    }
+
+
+The `errors` package also includes a new `Unwrap` function which returns the
+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
+
+As mentioned earlier, it is common to use the `fmt.Errorf` function to add additional information to an error.
+
+    if err != nil {
+        return fmt.Errorf("decompress %v: %v", name, err)
+    }
+
+In Go 1.13, the `fmt.Errorf` function supports a new `%w` verb. When this verb
+is present, the error returned by `fmt.Errorf` will have an `Unwrap` method
+returning the argument of `%w`, which must be an error. In all other ways, `%w`
+is identical to `%v`.
+
+    if err != nil {
+        // Return an error which unwraps to err.
+        return fmt.Errorf("decompress %v: %w", name, err)
+    }
+
+Wrapping an error with `%w` makes it available to `errors.Is` and `errors.As`:
+
+    err := fmt.Errorf("access denied: %w”, ErrPermission)
+    ...
+    if errors.Is(err, ErrPermission) ...
+
+
+** 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
+the original. There is no single answer to this question; it depends on the
+context in which the new error is created. Wrap an error to expose it to
+callers. Do not wrap an error when doing so would expose implementation details.
+
+As one example, imagine a `Parse` function which reads a complex data structure
+from an `io.Reader`. If an error occurs, we wish to report the line and column
+number at which it occurred. If the error occurs while reading from the
+`io.Reader`, we will want to wrap that error to allow inspection of the
+underlying problem. Since the caller provided the `io.Reader` to the function,
+it makes sense to expose the error produced by it.
+
+In contrast, a function which makes several calls to a database probably should
+not return an error which unwraps to the result of one of those calls. If the
+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)`
+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
+caller could reasonably write
+
+    err := pkg.LookupUser(...)
+    if errors.Is(err, sql.ErrNoRows) …
+
+At that point, the function must always return `sql.ErrNoRows` if you don't want
+to break your clients, even if you switch to a different database package. In
+other words, wrapping an error makes that error part of your API. If you don't
+want to commit to supporting that error as part of your API in the future, you
+shouldn't wrap the error.
+
+It’s important to remember that whether you wrap or not, the error text will be
+the same. A _person_ trying to understand the error will have the same information
+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
+
+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
+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]]
+which compares an error against a template, considering only fields which are
+non-zero in the template:
+
+    type Error struct {
+        Path string
+        User string
+    }
+
+    func (e *Error) Is(target error) bool {
+        t, ok := target.(*Error)
+        if !ok {
+            return false
+        }
+        return (e.Path == t.Path || t.Path == "") &&
+               (e.User == t.User || t.User == "")
+    }
+
+    if errors.Is(err, &Error{User: "someuser"}) {
+        // err's User field is "someuser".
+    }
+
+The `errors.As` function similarly consults an `As` method when present.
+
+* 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
+returning errors with properties that should not be relied upon.
+
+The simplest specification is to say that operations either succeed or fail,
+returning a nil or non-nil error value respectively. In many cases, no further
+information is needed.
+
+If we wish a function to return an identifiable error condition, such as "item
+not found," we might return an error wrapping a sentinel.
+
+    var ErrNotFound = errors.New("not found")
+
+    // FetchItem returns the named item.
+    //
+    // If no item with the name exists, FetchItem returns an error
+    // wrapping ErrNotFound.
+    func FetchItem(name string) (*Item, error) {
+        if itemNotFound(name) {
+            return nil, fmt.Errorf("%q: %w", name, ErrNotFound)
+        }
+        // ...
+    }
+
+There are other existing patterns for providing errors which can be semantically
+examined by the caller, such as directly returning a sentinel value, a specific
+type, or a value which can be examined with a predicate function.
+
+In all cases, care should be taken not to expose internal details to the user.
+As we touched on in "Whether to Wrap" above, when you return
+an error from another package you should convert the error to a form that does
+not expose the underlying error, unless you are willing to commit to returning
+that specific error in the future.
+
+    f, err := os.Open(filename)
+    if err != nil {
+        // The *os.PathError returned by os.Open is an internal detail.
+        // To avoid exposing it to the caller, repackage it as a new
+        // error with the same text. We use the %v formatting verb, since
+        // %w would permit the caller to unwrap the original *os.PathError.
+        return fmt.Errorf("%v", err)
+    }
+
+If a function is defined as returning an error wrapping some sentinel or type,
+do not return the underlying error directly.
+
+    var ErrPermission = errors.New("permission denied")
+
+    // DoSomething returns an error wrapping ErrPermission if the user
+    // does not have permission to do something.
+    func DoSomething() {
+        if !userHasPermission() {
+            // If we return ErrPermission directly, callers might come
+            // to depend on the exact error value, writing code like this:
+            //
+            //     if err := pkg.DoSomething(); err == pkg.ErrPermission { … }
+            //
+            // This will cause problems if we want to add additional
+            // context to the error in the future. To avoid this, we
+            // return an error wrapping the sentinel so that users must
+            // always unwrap it:
+            //
+            //     if err := pkg.DoSomething(); errors.Is(err, pkg.ErrPermission) { ... }
+            return fmt.Errorf("%w", ErrPermission)
+        }
+        // ...
+    }
+
+* 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
+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]],
+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.
