Skip to content
This repository was archived by the owner on Dec 1, 2021. It is now read-only.
This repository was archived by the owner on Dec 1, 2021. It is now read-only.

Proposal: Unpack standard library error wrapping types #112

@spenczar

Description

@spenczar

There are several error types in the standard library that wrap errors. net/url.Error, for example, 'reports an error and the operation and URL that caused it.' This error type is used (among other places) within the net/http.Client to annotate any errors it gets from its http.RoundTripper transport.

As a result, this test (for example) would not pass:

package main

import (
	"fmt"
	"net/http"
	"testing"

	"github.com/pkg/errors"
)

// failingTransport is a http.RoundTripper which always returns an error.
type failingTransport struct {
	err error // the error to return
}

func (t failingTransport) RoundTrip(*http.Request) (*http.Response, error) {
	return nil, t.err
}

func TestClientErrorsCanBeCaused(t *testing.T) {
	rootErr := fmt.Errorf("some root cause")
	c := &http.Client{
		Transport: &failingTransport{rootErr},
	}
	_, err := c.Get("bogus")
	cause := errors.Cause(err)
	if cause != rootErr {
		t.Errorf("err cause is %q, want %q", cause, rootErr)
	}
}
-> % go test -v ./errwrap_test.go
=== RUN   TestClientErrorsCanBeCaused
--- FAIL: TestClientErrorsCanBeCaused (0.00s)
	errwrap_test.go:28: err cause is "Get bogus: some root cause", want "some root cause"
FAIL
exit status 1
FAIL	command-line-arguments	1.090s

I think that test should pass, though. Otherwise, I need to write my own series of type assertions to unpack the real root cause. The errors package could unpack the standard library types which are clearly wrappers. I think those are these:

All of these may be useful, but I think the most important are the net ones, in my experience.

The implementation seems straightforward, if you're willing to accept the smelliness of a series of special-case type assertions in the Cause function.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions