From 7df585ea5372f389daf5945fbde9d53706545311 Mon Sep 17 00:00:00 2001 From: Adam Yeats Date: Wed, 21 Aug 2024 13:09:33 +0100 Subject: [PATCH] Refactor error_source.go --- experimental/errorsource/error_source.go | 45 ++++++++++++++----- experimental/errorsource/error_source_test.go | 12 ++--- 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/experimental/errorsource/error_source.go b/experimental/errorsource/error_source.go index 50799c85c..6e276a6ef 100644 --- a/experimental/errorsource/error_source.go +++ b/experimental/errorsource/error_source.go @@ -37,23 +37,48 @@ func (r Error) ErrorSource() backend.ErrorSource { return r.source } +// Options provides options for error source functions +type Options struct { + // Override will override the error source if it already exists + Override bool +} + +// WithOverride will set the override option when creating an error source +// This will override the error source if it already exists +func WithOverride() func(*Options) { + return func(s *Options) { + s.Override = true + } +} + // PluginError will apply the source as plugin -func PluginError(err error, override bool) error { - return SourceError(backend.ErrorSourcePlugin, err, override) +func PluginError(err error, options ...func(*Options)) error { + return ErrorWithSource(err, backend.ErrorSourcePlugin, options...) } // DownstreamError will apply the source as downstream -func DownstreamError(err error, override bool) error { - return SourceError(backend.ErrorSourceDownstream, err, override) +func DownstreamError(err error, options ...func(*Options)) error { + return ErrorWithSource(err, backend.ErrorSourceDownstream, options...) } // SourceError returns an error with the source // If source is already defined, it will return it, or you can override -func SourceError(source backend.ErrorSource, err error, override bool) Error { +func ErrorWithSource(err error, source backend.ErrorSource, options ...func(*Options)) Error { var sourceError Error - if errors.As(err, &sourceError) && !override { + + opts := &Options{ + // default to not override + Override: false, + } + + for _, o := range options { + o(opts) + } + + if errors.As(err, &sourceError) && !opts.Override { return sourceError // already has a source } + return Error{ source: source, err: err, @@ -61,7 +86,7 @@ func SourceError(source backend.ErrorSource, err error, override bool) Error { } // Response returns an error DataResponse given status, source of the error and message. -func Response(err error) backend.DataResponse { +func ResponseWithErrorSource(err error) backend.DataResponse { var e Error if !errors.As(err, &e) { // generic error, default to "plugin" error source @@ -86,17 +111,17 @@ func FromStatus(status backend.Status) backend.ErrorSource { // AddPluginErrorToResponse adds the error as plugin error source to the response // if the error already has a source, the existing source will be used func AddPluginErrorToResponse(refID string, response *backend.QueryDataResponse, err error) *backend.QueryDataResponse { - return AddErrorToResponse(refID, response, PluginError(err, false)) + return AddErrorToResponse(refID, response, PluginError(err)) } // AddDownstreamErrorToResponse adds the error as downstream source to the response // if the error already has a source, the existing source will be used func AddDownstreamErrorToResponse(refID string, response *backend.QueryDataResponse, err error) *backend.QueryDataResponse { - return AddErrorToResponse(refID, response, DownstreamError(err, false)) + return AddErrorToResponse(refID, response, DownstreamError(err)) } // AddErrorToResponse adds the error to the response func AddErrorToResponse(refID string, response *backend.QueryDataResponse, err error) *backend.QueryDataResponse { - response.Responses[refID] = Response(err) + response.Responses[refID] = ResponseWithErrorSource(err) return response } diff --git a/experimental/errorsource/error_source_test.go b/experimental/errorsource/error_source_test.go index f8af12c16..0c98420f0 100644 --- a/experimental/errorsource/error_source_test.go +++ b/experimental/errorsource/error_source_test.go @@ -26,21 +26,21 @@ func TestResponse(t *testing.T) { }, { name: "downstream error", - err: DownstreamError(errors.New("bad gateway"), false), + err: DownstreamError(errors.New("bad gateway")), expStatus: 0, expErrorMessage: "bad gateway", expErrorSource: backend.ErrorSourceDownstream, }, { name: "plugin error", - err: PluginError(errors.New("internal error"), false), + err: PluginError(errors.New("internal error")), expStatus: 0, expErrorMessage: "internal error", expErrorSource: backend.ErrorSourcePlugin, }, } { t.Run(tc.name, func(t *testing.T) { - res := Response(tc.err) + res := ResponseWithErrorSource(tc.err) require.Error(t, res.Error) require.Equal(t, tc.expStatus, res.Status) require.Equal(t, tc.expErrorMessage, res.Error.Error()) @@ -76,7 +76,7 @@ func TestResponseWithOptions(t *testing.T) { }, } { t.Run(tc.name, func(t *testing.T) { - res := Response(tc.err) + res := ResponseWithErrorSource(tc.err) require.Error(t, res.Error) require.Equal(t, tc.expStatus, res.Status) require.Equal(t, tc.expErrorMessage, res.Error.Error()) @@ -88,8 +88,8 @@ func TestResponseWithOptions(t *testing.T) { func TestError(t *testing.T) { err := errors.New("boom") require.False(t, backend.IsDownstreamError(err)) - pErr := PluginError(err, true) + pErr := PluginError(err, WithOverride()) require.False(t, backend.IsDownstreamError(pErr)) - dErr := DownstreamError(err, true) + dErr := DownstreamError(err, WithOverride()) require.True(t, backend.IsDownstreamError(dErr)) }