From 419ea1639230c5a7613962cbcbe0eb8b9e1ad078 Mon Sep 17 00:00:00 2001 From: Máximo Cuadros Date: Wed, 28 Oct 2015 15:02:25 +0100 Subject: clients: helpful error handling --- clients/common/common.go | 41 +++++++++++++++++++++++++++++++++++++++-- clients/http/common.go | 13 ++++++++++--- clients/http/common_test.go | 36 ++++++++++++++++++++++++++++++++++++ clients/http/git_upload_pack.go | 6 +++--- 4 files changed, 88 insertions(+), 8 deletions(-) (limited to 'clients') diff --git a/clients/common/common.go b/clients/common/common.go index 4204cb7..d29706d 100644 --- a/clients/common/common.go +++ b/clients/common/common.go @@ -1,6 +1,7 @@ package common import ( + "errors" "fmt" "io/ioutil" "net/url" @@ -12,6 +13,10 @@ import ( "gopkg.in/sourcegraph/go-vcsurl.v1" ) +var ( + NotFoundErr = errors.New("repository not found") +) + const GitUploadPackServiceName = "git-upload-pack" type Endpoint string @@ -19,7 +24,7 @@ type Endpoint string func NewEndpoint(url string) (Endpoint, error) { vcs, err := vcsurl.Parse(url) if err != nil { - return "", err + return "", NewPermanentError(err) } link := vcs.Link() @@ -88,7 +93,7 @@ type GitUploadPackInfo struct { func NewGitUploadPackInfo(d *pktline.Decoder) (*GitUploadPackInfo, error) { info := &GitUploadPackInfo{} if err := info.read(d); err != nil { - return nil, err + return nil, NewUnexpectedError(err) } return info, nil @@ -164,3 +169,35 @@ func (r *GitUploadPackRequest) Reader() *strings.Reader { return e.Reader() } + +type PermanentError struct { + err error +} + +func NewPermanentError(err error) *PermanentError { + if err == nil { + return nil + } + + return &PermanentError{err: err} +} + +func (e *PermanentError) Error() string { + return fmt.Sprintf("permanent client error: %s", e.err.Error()) +} + +type UnexpectedError struct { + err error +} + +func NewUnexpectedError(err error) *UnexpectedError { + if err == nil { + return nil + } + + return &UnexpectedError{err: err} +} + +func (e *UnexpectedError) Error() string { + return fmt.Sprintf("unexpected client error: %s", e.err.Error()) +} diff --git a/clients/http/common.go b/clients/http/common.go index a0f012e..2a2808c 100644 --- a/clients/http/common.go +++ b/clients/http/common.go @@ -3,18 +3,25 @@ package http import ( "fmt" "net/http" + + "gopkg.in/src-d/go-git.v2/clients/common" ) type HTTPError struct { Response *http.Response } -func NewHTTPError(r *http.Response) *HTTPError { +func NewHTTPError(r *http.Response) error { if r.StatusCode >= 200 && r.StatusCode < 300 { return nil } - return &HTTPError{r} + err := &HTTPError{r} + if r.StatusCode == 404 || r.StatusCode == 401 { + return common.NewPermanentError(common.NotFoundErr) + } + + return common.NewUnexpectedError(err) } func (e *HTTPError) StatusCode() int { @@ -22,7 +29,7 @@ func (e *HTTPError) StatusCode() int { } func (e *HTTPError) Error() string { - return fmt.Sprintf("Error requesting %q status code: %d", + return fmt.Sprintf("unexpected requesting %q status code: %d", e.Response.Request.URL, e.Response.StatusCode, ) } diff --git a/clients/http/common_test.go b/clients/http/common_test.go index b672801..7bd9708 100644 --- a/clients/http/common_test.go +++ b/clients/http/common_test.go @@ -1,9 +1,45 @@ package http import ( + "net/http" "testing" . "gopkg.in/check.v1" ) func Test(t *testing.T) { TestingT(t) } + +type SuiteCommon struct{} + +var _ = Suite(&SuiteCommon{}) + +func (s *SuiteCommon) TestNewHTTPError200(c *C) { + res := &http.Response{StatusCode: 200} + res.StatusCode = 200 + err := NewHTTPError(res) + c.Assert(err, IsNil) +} + +func (s *SuiteCommon) TestNewHTTPError401(c *C) { + s.testNewHTTPError(c, 401, "permanent client error.*not found.*") +} + +func (s *SuiteCommon) TestNewHTTPError404(c *C) { + s.testNewHTTPError(c, 404, "permanent client error.*not found.*") +} + +func (s *SuiteCommon) TestNewHTTPError40x(c *C) { + s.testNewHTTPError(c, 402, "unexpected client error.*") +} + +func (s *SuiteCommon) testNewHTTPError(c *C, code int, msg string) { + req, _ := http.NewRequest("GET", "foo", nil) + res := &http.Response{ + StatusCode: code, + Request: req, + } + + err := NewHTTPError(res) + c.Assert(err, NotNil) + c.Assert(err, ErrorMatches, msg) +} diff --git a/clients/http/git_upload_pack.go b/clients/http/git_upload_pack.go index 7e837e1..1c22dbf 100644 --- a/clients/http/git_upload_pack.go +++ b/clients/http/git_upload_pack.go @@ -50,7 +50,7 @@ func (s *GitUploadPackService) Fetch(r *common.GitUploadPackRequest) (io.ReadClo h := make([]byte, 8) if _, err := res.Body.Read(h); err != nil { - return nil, err + return nil, common.NewUnexpectedError(err) } return res.Body, nil @@ -64,14 +64,14 @@ func (s *GitUploadPackService) doRequest(method, url string, content *strings.Re req, err := http.NewRequest(method, url, body) if err != nil { - return nil, err + return nil, common.NewPermanentError(err) } s.applyHeadersToRequest(req, content) res, err := s.Client.Do(req) if err != nil { - return nil, err + return nil, common.NewUnexpectedError(err) } if err := NewHTTPError(res); err != nil { -- cgit