Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 13 additions & 32 deletions docstore/docstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,13 +299,12 @@ func (e ActionListError) Error() string {
// Unwrap returns the error in e, if there is exactly one. If there is more than one
Comment thread
Megakuul marked this conversation as resolved.
Outdated
// error, Unwrap returns nil, since there is no way to determine which should be
// returned.
func (e ActionListError) Unwrap() error {
if len(e) == 1 {
return e[0].Err
func (e ActionListError) Unwrap() []error {
errs := []error{}
for _, err := range e {
errs = append(errs, err.Err)
}
// Return nil when e is nil, or has more than one error.
// When there are multiple errors, it doesn't make sense to return any of them.
return nil
return errs
}

// BeforeDo takes a callback function that will be called before the ActionList is
Expand Down Expand Up @@ -558,55 +557,37 @@ func (a *Action) String() string {
// Create is a convenience for building and running a single-element action list.
// See ActionList.Create.
func (c *Collection) Create(ctx context.Context, doc Document) error {
if err := c.Actions().Create(doc).Do(ctx); err != nil {
return err.(ActionListError).Unwrap()
}
return nil
return c.Actions().Create(doc).Do(ctx)
}

// Replace is a convenience for building and running a single-element action list.
// See ActionList.Replace.
func (c *Collection) Replace(ctx context.Context, doc Document) error {
if err := c.Actions().Replace(doc).Do(ctx); err != nil {
return err.(ActionListError).Unwrap()
}
return nil
return c.Actions().Replace(doc).Do(ctx)
}

// Put is a convenience for building and running a single-element action list.
// See ActionList.Put.
func (c *Collection) Put(ctx context.Context, doc Document) error {
if err := c.Actions().Put(doc).Do(ctx); err != nil {
return err.(ActionListError).Unwrap()
}
return nil
return c.Actions().Put(doc).Do(ctx)
}

// Delete is a convenience for building and running a single-element action list.
// See ActionList.Delete.
func (c *Collection) Delete(ctx context.Context, doc Document) error {
if err := c.Actions().Delete(doc).Do(ctx); err != nil {
return err.(ActionListError).Unwrap()
}
return nil
return c.Actions().Delete(doc).Do(ctx)
}

// Get is a convenience for building and running a single-element action list.
// See ActionList.Get.
func (c *Collection) Get(ctx context.Context, doc Document, fps ...FieldPath) error {
if err := c.Actions().Get(doc, fps...).Do(ctx); err != nil {
return err.(ActionListError).Unwrap()
}
return nil
return c.Actions().Get(doc, fps...).Do(ctx)
}

// Update is a convenience for building and running a single-element action list.
// See ActionList.Update.
func (c *Collection) Update(ctx context.Context, doc Document, mods Mods) error {
if err := c.Actions().Update(doc, mods).Do(ctx); err != nil {
return err.(ActionListError).Unwrap()
}
return nil
return c.Actions().Update(doc, mods).Do(ctx)
}

func parseFieldPath(fp FieldPath) ([]string, error) {
Expand Down Expand Up @@ -698,9 +679,9 @@ func wrapError(c driver.Collection, err error) error {
return err
}
if _, ok := err.(*gcerr.Error); ok {
return err
return gcerrors.Wrap(err)
Comment thread
Megakuul marked this conversation as resolved.
Outdated
}
return gcerr.New(c.ErrorCode(err), err, 2, "docstore")
return gcerrors.Wrap(gcerr.New(c.ErrorCode(err), err, 2, "docstore"))
Comment thread
Megakuul marked this conversation as resolved.
Outdated
}

// ErrorAs converts i to driver-specific types. See
Expand Down
6 changes: 2 additions & 4 deletions docstore/docstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package docstore

import (
"context"
"errors"
"reflect"
"testing"
"time"
Expand Down Expand Up @@ -118,10 +119,7 @@ func TestClosedErrors(t *testing.T) {

check := func(err error) {
t.Helper()
if alerr, ok := err.(ActionListError); ok {
err = alerr.Unwrap()
}
if err != errClosed {
if !errors.Is(err, errClosed) {
t.Errorf("got %v, want errClosed", err)
}
}
Expand Down
27 changes: 27 additions & 0 deletions gcerrors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,33 @@ const (
DeadlineExceeded ErrorCode = gcerr.DeadlineExceeded
)

// TODO: just as an example, hypothetically this would be implemented for all errors
type AlreadyExistsError struct {
Comment thread
Megakuul marked this conversation as resolved.
Outdated
err error
}

func (a *AlreadyExistsError) Error() string {
return a.err.Error()
}

func (a *AlreadyExistsError) Unwrap() error {
return a.err
}

// Wrap returns the Error struct that corresponds to the ErrorCode of the underlying error.
// If err is not a go-cloud error it just returns the error.
func Wrap(err error) error {
var e *gcerr.Error
if !errors.As(err, &e) {
return err
}
switch e.Code {
case gcerr.AlreadyExists:
return &AlreadyExistsError{err: err}
}
return err
}

// Code returns the ErrorCode of err if it, or some error it wraps, is an *Error.
// If err is context.Canceled or context.DeadlineExceeded, or wraps one of those errors,
// it returns the Canceled or DeadlineExceeded codes, respectively.
Expand Down