From 8e812b7ac028cce91166207f7cebf02338f92206 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Tue, 23 Jan 2018 21:40:51 +0100 Subject: [PATCH] errors: Make Cause() unwrap *url.Error --- internal/errors/{wrap.go => errors.go} | 35 ++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 5 deletions(-) rename internal/errors/{wrap.go => errors.go} (56%) diff --git a/internal/errors/wrap.go b/internal/errors/errors.go similarity index 56% rename from internal/errors/wrap.go rename to internal/errors/errors.go index 99d6e88ba..aa2ff6f2b 100644 --- a/internal/errors/wrap.go +++ b/internal/errors/errors.go @@ -1,11 +1,10 @@ package errors -import "github.com/pkg/errors" +import ( + "net/url" -// Cause returns the cause of an error. -func Cause(err error) error { - return errors.Cause(err) -} + "github.com/pkg/errors" +) // New creates a new error based on message. Wrapped so that this package does // not appear in the stack trace. @@ -22,3 +21,29 @@ var Wrap = errors.Wrap // Wrapf returns an error annotating err with the format specifier. If err is // nil, Wrapf returns nil. var Wrapf = errors.Wrapf + +// Cause returns the cause of an error. It will also unwrap certain errors, +// e.g. *url.Error returned by the net/http client. +func Cause(err error) error { + type Causer interface { + Cause() error + } + + for { + // unwrap *url.Error + if urlErr, ok := err.(*url.Error); ok { + err = urlErr.Err + continue + } + + // if err is a Causer, return the cause for this error. + if c, ok := err.(Causer); ok { + err = c.Cause() + continue + } + + break + } + + return err +}