From 587443169acd10f7f86d1989dc8aaf189e645e98 Mon Sep 17 00:00:00 2001 From: Cody Oss <6331106+codyoss@users.noreply.github.com> Date: Mon, 22 May 2023 10:52:13 -0500 Subject: [PATCH] feat(apierror): add method to return HTTP status code conditionally (#274) Fixes: #229 --- v2/apierror/apierror.go | 10 ++++++++++ v2/apierror/apierror_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/v2/apierror/apierror.go b/v2/apierror/apierror.go index b88393d..d785a06 100644 --- a/v2/apierror/apierror.go +++ b/v2/apierror/apierror.go @@ -349,3 +349,13 @@ func parseHTTPDetails(gae *googleapi.Error) ErrDetails { return parseDetails(details) } + +// HTTPCode returns the underlying HTTP response status code. This method returns +// `-1` if the underlying error is a [google.golang.org/grpc/status.Status]. To +// check gRPC error codes use [google.golang.org/grpc/status.Code]. +func (a *APIError) HTTPCode() int { + if a.httpErr == nil { + return -1 + } + return a.httpErr.Code +} diff --git a/v2/apierror/apierror_test.go b/v2/apierror/apierror_test.go index 7cb7305..c3f28dc 100644 --- a/v2/apierror/apierror_test.go +++ b/v2/apierror/apierror_test.go @@ -519,3 +519,35 @@ func toAPIError(e *errdetails.ErrorInfo) *APIError { details: ErrDetails{ErrorInfo: e}, } } + +func TestHTTPCode(t *testing.T) { + tests := []struct { + name string + apierr *APIError + want int + }{ + { + name: "basic http error", + apierr: &APIError{httpErr: &googleapi.Error{Code: 418}}, + want: 418, + }, + { + name: "http error, with unknown status", + apierr: &APIError{httpErr: &googleapi.Error{Code: 418}, status: status.New(codes.Unknown, "???")}, + want: 418, + }, + { + name: "gRPC error", + apierr: &APIError{status: status.New(codes.DataLoss, "where did it go?")}, + want: -1, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.apierr.HTTPCode(); got != tt.want { + t.Errorf("HTTPCode() = %v, want %v", got, tt.want) + } + }) + } +}