Skip to content

Commit

Permalink
feat(googleapi): inject gax apierror.APIError into googleapi.Error
Browse files Browse the repository at this point in the history
  • Loading branch information
quartzmo committed Nov 2, 2022
1 parent 0d7f97a commit 07b0d29
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
6 changes: 6 additions & 0 deletions googleapi/googleapi.go
Expand Up @@ -79,6 +79,8 @@ type Error struct {
Header http.Header

Errors []ErrorItem
// Err is a wrapped apierror.APIError, typically derived from this Error.
Err error
}

// ErrorItem is a detailed error code & message from the Google API frontend.
Expand Down Expand Up @@ -122,6 +124,10 @@ func (e *Error) Error() string {
return buf.String()
}

func (e *Error) Unwrap() error {
return e.Err
}

type errorReply struct {
Error *Error `json:"error"`
}
Expand Down
22 changes: 22 additions & 0 deletions internal/gensupport/error.go
@@ -0,0 +1,22 @@
// Copyright 2020 Google LLC. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gensupport

import (
"github.com/googleapis/gax-go/v2/apierror"
"google.golang.org/api/googleapi"
)

// WrapError creates an apierror.APIError from err (one that
// does not wrap err), wraps it in err, and returns err. If
// err is not a googleapi.Error (or a gRPC Status), it returns
// err without modification.
func WrapError(err *googleapi.Error) *googleapi.Error {
// TODO: Update this call to apierror.FromWrappingError once it is available.
if apiError, ok := apierror.FromError(err); ok {
err.Err = apiError
}
return err
}
48 changes: 48 additions & 0 deletions internal/gensupport/error_test.go
@@ -0,0 +1,48 @@
// Copyright 2019 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gensupport

import (
"errors"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/googleapis/gax-go/v2/apierror"
"google.golang.org/api/googleapi"
"google.golang.org/genproto/googleapis/rpc/errdetails"
"google.golang.org/protobuf/proto"
)

func TestWrapError(t *testing.T) {
// The error format v2 for Google JSON REST APIs, per https://cloud.google.com/apis/design/errors#http_mapping.
jsonErrStr := "{\"error\":{\"details\":[{\"@type\":\"type.googleapis.com/google.rpc.ErrorInfo\", \"reason\":\"just because\", \"domain\":\"tests\"}]}}"
hae := &googleapi.Error{
Body: jsonErrStr,
}
hae = WrapError(hae)

var aerr *apierror.APIError
if ok := errors.As(hae, &aerr); !ok {
t.Errorf("got false, want true")
}

httpErrInfo := &errdetails.ErrorInfo{Reason: "just because", Domain: "tests"}
details := apierror.ErrDetails{ErrorInfo: httpErrInfo}
if diff := cmp.Diff(aerr.Details(), details, cmp.Comparer(proto.Equal)); diff != "" {
t.Errorf("got(-), want(+),: \n%s", diff)
}
if s := aerr.Reason(); s != "just because" {
t.Errorf("Reason() got %s, want 'just because'", s)
}
if s := aerr.Domain(); s != "tests" {
t.Errorf("Domain() got %s, want nil", s)
}
if err := aerr.Unwrap(); err != nil {
t.Errorf("Unwrap() got %T, want nil", err)
}
if m := aerr.Metadata(); m != nil {
t.Errorf("Metadata() got %v, want nil", m)
}
}

0 comments on commit 07b0d29

Please sign in to comment.