Skip to content

Commit

Permalink
Keep propagation of root error, instead of wrapped rest.Error
Browse files Browse the repository at this point in the history
  • Loading branch information
Dragomir-Ivanov committed May 13, 2020
1 parent b837ede commit 2e9eb16
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 67 deletions.
22 changes: 11 additions & 11 deletions rest/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,29 @@ type Error struct {
// NewError returns a rest.Error from an standard error.
//
// If the the inputted error is recognized, the appropriate rest.Error is mapped.
func NewError(err error) *Error {
func NewError(err error) (error, int) {
if Err, ok := err.(*Error); ok {
return Err
return err, Err.Code
}
switch err {
case context.Canceled:
return ErrClientClosedRequest
return ErrClientClosedRequest, ErrClientClosedRequest.Code
case context.DeadlineExceeded:
return ErrGatewayTimeout
return ErrGatewayTimeout, ErrGatewayTimeout.Code
case resource.ErrNotFound:
return ErrNotFound
return ErrNotFound, ErrNotFound.Code
case resource.ErrForbidden:
return ErrForbidden
return ErrForbidden, ErrForbidden.Code
case resource.ErrConflict:
return ErrConflict
return ErrConflict, ErrConflict.Code
case resource.ErrNotImplemented:
return ErrNotImplemented
return ErrNotImplemented, ErrNotImplemented.Code
case resource.ErrNoStorage:
return &Error{501, err.Error(), nil}
return &Error{501, err.Error(), nil}, 501
case nil:
return nil
return nil, 0
default:
return &Error{520, err.Error(), nil}
return err, 520
}
}

Expand Down
4 changes: 2 additions & 2 deletions rest/method_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ func listDelete(ctx context.Context, r *http.Request, route *RouteMatch) (status
}
total, err := route.Resource().Clear(ctx, q)
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
headers = http.Header{}
headers.Set("X-Total", strconv.Itoa(total))
Expand Down
8 changes: 4 additions & 4 deletions rest/method_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,17 @@ func listGet(ctx context.Context, r *http.Request, route *RouteMatch) (status in
list, err = rsc.Find(ctx, q)
}
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
if win := q.Window; win != nil && win.Offset > 0 {
list.Offset = win.Offset
}
for _, item := range list.Items {
item.Payload, err = q.Projection.Eval(ctx, item.Payload, restResource{rsc})
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
}
return 200, nil, list
Expand Down
8 changes: 4 additions & 4 deletions rest/method_item_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ func itemDelete(ctx context.Context, r *http.Request, route *RouteMatch) (status
q.Window = &query.Window{Limit: 1}
l, err := route.Resource().Find(ctx, q)
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
if len(l.Items) == 0 {
return ErrNotFound.Code, nil, ErrNotFound
Expand All @@ -28,8 +28,8 @@ func itemDelete(ctx context.Context, r *http.Request, route *RouteMatch) (status
return err.Code, nil, err
}
if err := route.Resource().Delete(ctx, original); err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
return 204, nil, nil
}
8 changes: 4 additions & 4 deletions rest/method_item_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ func itemGet(ctx context.Context, r *http.Request, route *RouteMatch) (status in
q.Window = &query.Window{Limit: 1}
list, err := rsrc.Find(ctx, q)
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
} else if len(list.Items) == 0 {
return ErrNotFound.Code, nil, ErrNotFound
}
Expand All @@ -40,8 +40,8 @@ func itemGet(ctx context.Context, r *http.Request, route *RouteMatch) (status in
}
item.Payload, err = q.Projection.Eval(ctx, item.Payload, restResource{rsrc})
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
return 200, nil, item
}
28 changes: 14 additions & 14 deletions rest/method_item_patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ func itemPatch(ctx context.Context, r *http.Request, route *RouteMatch) (status
q.Window = &query.Window{Limit: 1}
if l, err := rsrc.Find(ctx, q); err != nil {
// If item can't be fetch, return an error.
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
} else if len(l.Items) == 0 {
return ErrNotFound.Code, nil, ErrNotFound
} else {
Expand Down Expand Up @@ -96,21 +96,21 @@ func itemPatch(ctx context.Context, r *http.Request, route *RouteMatch) (status
}
item, err := resource.NewItem(doc)
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}

preHookEtag := item.ETag
if len(q.Projection) > 0 {
projected, err := q.Projection.Eval(ctx, item.Payload, restResource{rsrc})
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
preHookEtag, err = resource.GenEtag(projected)
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
}

Expand All @@ -120,23 +120,23 @@ func itemPatch(ctx context.Context, r *http.Request, route *RouteMatch) (status
// condition (i.e.: another thread modified the document between the Find()
// and the Store()).
if err = rsrc.Update(ctx, item, original); err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}

postHookEtag := item.ETag
// Evaluate projection so response gets the same format as read requests.
item.Payload, err = q.Projection.Eval(ctx, item.Payload, restResource{rsrc})
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}

if len(q.Projection) > 0 {
postHookEtag, err = resource.GenEtag(item.Payload)
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
}

Expand Down
32 changes: 16 additions & 16 deletions rest/method_item_put.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ func itemPut(ctx context.Context, r *http.Request, route *RouteMatch) (status in
var original *resource.Item
q.Window = &query.Window{Limit: 1}
if l, err := rsrc.Find(ctx, q); err != nil && err != ErrNotFound {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
} else if len(l.Items) == 1 {
original = l.Items[0]
}
Expand Down Expand Up @@ -79,21 +79,21 @@ func itemPut(ctx context.Context, r *http.Request, route *RouteMatch) (status in
}
item, err := resource.NewItem(doc)
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}

preHookEtag := item.ETag
if len(q.Projection) > 0 {
projected, err := q.Projection.Eval(ctx, item.Payload, restResource{rsrc})
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
preHookEtag, err = resource.GenEtag(projected)
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
}
// If we have an original item, pass it to the handler so we make sure
Expand All @@ -102,29 +102,29 @@ func itemPut(ctx context.Context, r *http.Request, route *RouteMatch) (status in
// is provided.
if original != nil {
if err = rsrc.Update(ctx, item, original); err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
} else {
if err = rsrc.Insert(ctx, []*resource.Item{item}); err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
}

postHookEtag := item.ETag
// Evaluate projection so response gets the same format as read requests.
item.Payload, err = q.Projection.Eval(ctx, item.Payload, restResource{rsrc})
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}

if len(q.Projection) > 0 {
postHookEtag, err = resource.GenEtag(item.Payload)
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
}

Expand Down
24 changes: 12 additions & 12 deletions rest/method_post.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,36 +32,36 @@ func listPost(ctx context.Context, r *http.Request, route *RouteMatch) (status i
}
item, err := resource.NewItem(doc)
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}

preHookEtag := item.ETag
if len(q.Projection) > 0 {
projected, err := q.Projection.Eval(ctx, item.Payload, restResource{rsrc})
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
preHookEtag, err = resource.GenEtag(projected)
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
}

// TODO: add support for batch insert
if err = rsrc.Insert(ctx, []*resource.Item{item}); err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}

postHookEtag := item.ETag
// Evaluate projection so response gets the same format as read requests.
item.Payload, err = q.Projection.Eval(ctx, item.Payload, restResource{rsrc})
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
// See https://www.subbu.org/blog/2008/10/location-vs-content-location
headers = http.Header{}
Expand All @@ -78,8 +78,8 @@ func listPost(ctx context.Context, r *http.Request, route *RouteMatch) (status i
if len(q.Projection) > 0 {
postHookEtag, err = resource.GenEtag(item.Payload)
if err != nil {
e = NewError(err)
return e.Code, nil, e
e, code := NewError(err)
return code, nil, e
}
}

Expand Down

0 comments on commit 2e9eb16

Please sign in to comment.