Skip to content

Commit

Permalink
pkg/errors dependency removed
Browse files Browse the repository at this point in the history
  • Loading branch information
solher committed Jul 26, 2017
1 parent bf4c80d commit bbba7fd
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 32 deletions.
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ The new `v2.0.0` version is a major evolution. It brings (sadly) some breaking c
- A less awkward API, more focused and I hope, clearer.
- All the goroutine magic purely and simply deleted.
- The weird custom logger replaced by a more standard and simple one.
- New powerful [pkg/errors](https://github.com/pkg/errors) based error handling.
- Context support allowing request cancellation.
- JWT support added.
- More lightweight than ever.
Expand Down Expand Up @@ -232,8 +231,6 @@ db.Run(ctx, nil, &requests.DropGraph{Name: "graphName", DropCollections: true})

## Error Handling

All the errors returned by Arangolite are wrapped using [pkg/errors](https://github.com/pkg/errors).

Errors can be handled using the provided basic testers:

```go
Expand Down
19 changes: 9 additions & 10 deletions database.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"log"
"net"
"net/http"
"runtime"
"time"

"github.com/pkg/errors"
"github.com/solher/arangolite/requests"
)

Expand Down Expand Up @@ -167,13 +167,13 @@ func (db *Database) Run(ctx context.Context, v interface{}, q Runnable) error {

result, err := db.followCursor(ctx, r)
if err != nil {
return errors.Wrap(err, "could not follow the query cursor")
return withMessage(err, "could not follow the query cursor")
}
if v == nil || result == nil || len(result) == 0 {
return nil
}
if err := json.Unmarshal(result, v); err != nil {
return errors.Wrap(err, "run result unmarshalling failed")
return withMessage(err, "run result unmarshalling failed")
}

return nil
Expand All @@ -191,24 +191,24 @@ func (db *Database) Send(ctx context.Context, q Runnable) (Response, error) {
bytes.NewBuffer(q.Generate()),
)
if err != nil {
return nil, errors.Wrap(err, "the http request generation failed")
return nil, withMessage(err, "the http request generation failed")
}

if err := db.auth.Apply(req); err != nil {
return nil, errors.Wrap(err, "authentication returned an error")
return nil, withMessage(err, "authentication returned an error")
}

res, err := db.sender.Send(ctx, db.cli, req)
if err != nil {
return nil, err
}
if res.parsed.Error {
err = errors.Wrap(errors.New(res.parsed.ErrorMessage), "the database execution returned an error")
err = withMessage(errors.New(res.parsed.ErrorMessage), "the database execution returned an error")
err = withErrorNum(err, res.parsed.ErrorNum)
}
if res.statusCode < 200 || res.statusCode >= 300 {
if err == nil {
err = errors.Errorf("the database HTTP request failed: status code %d", res.statusCode)
err = fmt.Errorf("the database HTTP request failed: status code %d", res.statusCode)
}
err = withStatusCode(err, res.statusCode)
}
Expand All @@ -229,10 +229,9 @@ func (db *Database) followCursor(ctx context.Context, r Response) ([]byte, error
if len(r.RawResult()) != 0 {
// Parsed result is not empty, so return this
return r.RawResult(), nil
} else {
// Return the raw result
return r.Raw(), nil
}
// Return the raw result
return r.Raw(), nil
}

buf := bytes.NewBuffer(r.RawResult()[:len(r.RawResult())-1])
Expand Down
12 changes: 12 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
package arangolite

import (
"fmt"
)

func withMessage(err error, message string) error {
if err == nil {
return nil
}
return fmt.Errorf("%s: %s", message, err.Error())
}

type arangoError struct {
error
statusCode int
Expand All @@ -26,6 +37,7 @@ func withErrorNum(err error, errorNum int) error {
return aError
}

// HasStatusCode returns true when one of the given error status code matches the one returned by the database.
func HasStatusCode(err error, statusCode ...int) bool {
e, ok := err.(arangoError)
if !ok {
Expand Down
21 changes: 10 additions & 11 deletions errors_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package arangolite

import (
"errors"
"fmt"
"testing"

"github.com/pkg/errors"
)

func assertEqual(t *testing.T, a interface{}, b interface{}, messages ...string) {
Expand All @@ -25,7 +24,7 @@ func assertTrue(t *testing.T, a interface{}, message ...string) {
}

func TestGetStatusCode(t *testing.T) {
err := errors.Wrap(errors.New("Error message"), "the database execution returned an error")
err := withMessage(errors.New("Error message"), "the database execution returned an error")
err = withErrorNum(err, 1207)
err = withStatusCode(err, 409)
statusCode, ok := GetStatusCode(err)
Expand All @@ -34,14 +33,14 @@ func TestGetStatusCode(t *testing.T) {
}

func TestHasStatusCode(t *testing.T) {
err := errors.Wrap(errors.New("Error message"), "the database execution returned an error")
err := withMessage(errors.New("Error message"), "the database execution returned an error")
err = withErrorNum(err, 1207)
err = withStatusCode(err, 409)
assertTrue(t, HasStatusCode(err, 409), "Status code does not match!")
}

func TestGetErrorNum(t *testing.T) {
err := errors.Wrap(errors.New("Error message"), "the database execution returned an error")
err := withMessage(errors.New("Error message"), "the database execution returned an error")
err = withErrorNum(err, 1207)
err = withStatusCode(err, 409)
errNum, ok := GetErrorNum(err)
Expand All @@ -50,40 +49,40 @@ func TestGetErrorNum(t *testing.T) {
}

func TestHasErrorNum(t *testing.T) {
err := errors.Wrap(errors.New("Error message"), "the database execution returned an error")
err := withMessage(errors.New("Error message"), "the database execution returned an error")
err = withErrorNum(err, 1207)
err = withStatusCode(err, 409)
assertTrue(t, HasErrorNum(err, 1207), "Error code does not match!")
}

func TestIsErrInvalidRequest(t *testing.T) {
err := errors.Wrap(errors.New("Error message"), "the database execution returned an error")
err := withMessage(errors.New("Error message"), "the database execution returned an error")
err = withStatusCode(err, 400)
assertTrue(t, IsErrInvalidRequest(err))
}

func TestIsErrUnauthorized(t *testing.T) {
err := errors.Wrap(errors.New("Error message"), "the database execution returned an error")
err := withMessage(errors.New("Error message"), "the database execution returned an error")
err = withStatusCode(err, 401)
assertTrue(t, IsErrUnauthorized(err))
}

func TestIsErrNotFound(t *testing.T) {
err := errors.Wrap(errors.New("Error message"), "the database execution returned an error")
err := withMessage(errors.New("Error message"), "the database execution returned an error")
err = withErrorNum(err, 1202)
err = withStatusCode(err, 403)
assertTrue(t, IsErrNotFound(err))
}

func TestIsErrForbidden(t *testing.T) {
err := errors.Wrap(errors.New("Error message"), "the database execution returned an error")
err := withMessage(errors.New("Error message"), "the database execution returned an error")
err = withErrorNum(err, 1202)
err = withStatusCode(err, 403)
assertTrue(t, IsErrForbidden(err))
}

func TestIsErrUnique(t *testing.T) {
err := errors.Wrap(errors.New("Error message"), "the database execution returned an error")
err := withMessage(errors.New("Error message"), "the database execution returned an error")
err = withErrorNum(err, 1210)
err = withStatusCode(err, 403)
assertTrue(t, IsErrUnique(err))
Expand Down
13 changes: 5 additions & 8 deletions senders.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ import (
"encoding/json"
"io/ioutil"
"net/http"

"strings"

"github.com/pkg/errors"
)

type sender interface {
Expand All @@ -26,19 +23,19 @@ func (s *basicSender) Send(ctx context.Context, cli *http.Client, req *http.Requ
}
res, err := cli.Do(req)
if err != nil {
return nil, errors.Wrap(err, "the database HTTP request failed")
return nil, withMessage(err, "the database HTTP request failed")
}

raw, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
return nil, errors.Wrap(err, "could not read the database response")
return nil, withMessage(err, "could not read the database response")
}

parsed := parsedResponse{}
if strings.Contains(res.Header.Get("Content-Type"), "application/json") {
if err := json.Unmarshal(raw, &parsed); err != nil {
return nil, errors.Wrap(err, "could not decode the json database response")
return nil, withMessage(err, "could not decode the json database response")
}
}

Expand Down Expand Up @@ -83,14 +80,14 @@ func (r *response) Cursor() string {

func (r *response) Unmarshal(v interface{}) error {
if err := json.Unmarshal(r.raw, v); err != nil {
return errors.Wrap(err, "response unmarshalling failed")
return withMessage(err, "response unmarshalling failed")
}
return nil
}

func (r *response) UnmarshalResult(v interface{}) error {
if err := json.Unmarshal(r.parsed.Result, v); err != nil {
return errors.Wrap(err, "response result unmarshalling failed")
return withMessage(err, "response result unmarshalling failed")
}
return nil
}

0 comments on commit bbba7fd

Please sign in to comment.