From 797daa1f1f6f0a79d5f297cfd765d075bb24da5c Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Fri, 30 Aug 2024 16:21:34 +0700 Subject: [PATCH 01/12] feat: prometheus error handling in getTriggerFromRequest and in triggerCheck --- api/handler/triggers.go | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/api/handler/triggers.go b/api/handler/triggers.go index 090ed6607..d8b413d16 100644 --- a/api/handler/triggers.go +++ b/api/handler/triggers.go @@ -9,6 +9,8 @@ import ( "strings" "time" + prometheus "github.com/prometheus/client_golang/api/prometheus/v1" + "github.com/go-chi/chi" "github.com/go-chi/render" "github.com/moira-alert/moira" @@ -153,7 +155,7 @@ func createTrigger(writer http.ResponseWriter, request *http.Request) { func getTriggerFromRequest(request *http.Request) (*dto.Trigger, *api.ErrorResponse) { trigger := &dto.Trigger{} if err := render.Bind(request, trigger); err != nil { - switch err.(type) { // nolint:errorlint + switch typedErr := err.(type) { // nolint:errorlint case local.ErrParseExpr, local.ErrEvalExpr, local.ErrUnknownFunction: return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid graphite targets: %s", err.Error())) case expression.ErrInvalidExpression: @@ -169,6 +171,13 @@ func getTriggerFromRequest(request *http.Request) (*dto.Trigger, *api.ErrorRespo return nil, response case *json.UnmarshalTypeError: return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid payload: %s", err.Error())) + case *prometheus.Error: + switch typedErr.Type { + case prometheus.ErrBadData: + return nil, api.ErrorInvalidRequest(fmt.Errorf("prometheus: %w", err)) + default: + return nil, api.ErrorInternalServer(err) + } default: return nil, api.ErrorInternalServer(err) } @@ -208,10 +217,21 @@ func triggerCheck(writer http.ResponseWriter, request *http.Request) { response := dto.TriggerCheckResponse{} if err := render.Bind(request, trigger); err != nil { - switch err.(type) { // nolint:errorlint + switch typedErr := err.(type) { // nolint:errorlint case expression.ErrInvalidExpression, local.ErrParseExpr, local.ErrEvalExpr, local.ErrUnknownFunction: - // TODO write comment, why errors are ignored, it is not obvious. - // In getTriggerFromRequest these types of errors lead to 400. + // TODO: move ErrInvalidExpression to separate case + + // These errors are skipped because if there are error from local source then it will be caught in + // dto.TargetVerification and will be explained in detail. + case *prometheus.Error: + switch typedErr.Type { + case prometheus.ErrBadData: + render.Render(writer, request, api.ErrorInvalidRequest(fmt.Errorf("prometheus: %w", err))) //nolint + return + default: + render.Render(writer, request, api.ErrorInvalidRequest(err)) //nolint + return + } default: render.Render(writer, request, api.ErrorInvalidRequest(err)) //nolint return From f02ae6c61c1da5c188af60fd586d884713e01c1b Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Fri, 30 Aug 2024 18:24:06 +0700 Subject: [PATCH 02/12] refactor: error message --- api/handler/triggers.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/handler/triggers.go b/api/handler/triggers.go index d8b413d16..e26e72b74 100644 --- a/api/handler/triggers.go +++ b/api/handler/triggers.go @@ -174,7 +174,7 @@ func getTriggerFromRequest(request *http.Request) (*dto.Trigger, *api.ErrorRespo case *prometheus.Error: switch typedErr.Type { case prometheus.ErrBadData: - return nil, api.ErrorInvalidRequest(fmt.Errorf("prometheus: %w", err)) + return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid prometheus targets: %w", err)) default: return nil, api.ErrorInternalServer(err) } @@ -226,7 +226,7 @@ func triggerCheck(writer http.ResponseWriter, request *http.Request) { case *prometheus.Error: switch typedErr.Type { case prometheus.ErrBadData: - render.Render(writer, request, api.ErrorInvalidRequest(fmt.Errorf("prometheus: %w", err))) //nolint + render.Render(writer, request, api.ErrorInvalidRequest(fmt.Errorf("invalid prometheus targets: %w", err))) //nolint return default: render.Render(writer, request, api.ErrorInvalidRequest(err)) //nolint From 80eb5fdf49d7d6b7508b508c89ce08dee237c805 Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Tue, 3 Sep 2024 11:34:18 +0700 Subject: [PATCH 03/12] test: for handling errors returned from prometheus --- api/handler/triggers.go | 4 +- api/handler/triggers_test.go | 89 ++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/api/handler/triggers.go b/api/handler/triggers.go index e26e72b74..bdac9538c 100644 --- a/api/handler/triggers.go +++ b/api/handler/triggers.go @@ -174,9 +174,9 @@ func getTriggerFromRequest(request *http.Request) (*dto.Trigger, *api.ErrorRespo case *prometheus.Error: switch typedErr.Type { case prometheus.ErrBadData: - return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid prometheus targets: %w", err)) + return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid prometheus targets: %w", typedErr)) default: - return nil, api.ErrorInternalServer(err) + return nil, api.ErrorInternalServer(typedErr) } default: return nil, api.ErrorInternalServer(err) diff --git a/api/handler/triggers_test.go b/api/handler/triggers_test.go index 83d0a1bea..d998545ec 100644 --- a/api/handler/triggers_test.go +++ b/api/handler/triggers_test.go @@ -12,6 +12,8 @@ import ( "testing" "time" + prometheus "github.com/prometheus/client_golang/api/prometheus/v1" + "github.com/moira-alert/moira" "github.com/moira-alert/moira/api" dataBase "github.com/moira-alert/moira/database" @@ -139,6 +141,93 @@ func TestGetTriggerFromRequest(t *testing.T) { So(err, ShouldHaveSameTypeAs, api.ErrorInvalidRequest(fmt.Errorf(""))) }) }) + + Convey("With incorrect targets error", t, func() { + graphiteLocalSrc := mock_metric_source.NewMockMetricSource(mockCtrl) + graphiteRemoteSrc := mock_metric_source.NewMockMetricSource(mockCtrl) + prometheusSrc := mock_metric_source.NewMockMetricSource(mockCtrl) + allSourceProvider := metricSource.CreateTestMetricSourceProvider(graphiteLocalSrc, graphiteRemoteSrc, prometheusSrc) + + graphiteLocalSrc.EXPECT().GetMetricsTTLSeconds().Return(int64(3600)).AnyTimes() + graphiteRemoteSrc.EXPECT().GetMetricsTTLSeconds().Return(int64(3600)).AnyTimes() + prometheusSrc.EXPECT().GetMetricsTTLSeconds().Return(int64(3600)).AnyTimes() + + triggerWarnValue := 0.0 + triggerErrorValue := 1.0 + ttlState := moira.TTLState("NODATA") + triggerDTO := dto.Trigger{ + TriggerModel: dto.TriggerModel{ + ID: "test_id", + Name: "Test trigger", + Desc: new(string), + Targets: []string{"foo.bar"}, + WarnValue: &triggerWarnValue, + ErrorValue: &triggerErrorValue, + TriggerType: "rising", + Tags: []string{"Normal", "DevOps", "DevOpsGraphite-duty"}, + TTLState: &ttlState, + TTL: moira.DefaultTTL, + Schedule: &moira.ScheduleData{}, + Expression: "", + Patterns: []string{}, + ClusterId: moira.DefaultCluster, + MuteNewMetrics: false, + AloneMetrics: map[string]bool{}, + CreatedAt: &time.Time{}, + UpdatedAt: &time.Time{}, + CreatedBy: "", + UpdatedBy: "anonymous", + }, + } + + Convey("for prometheus remote", func() { + triggerDTO.TriggerSource = moira.PrometheusRemote + body, _ := json.Marshal(triggerDTO) + + Convey("with error type = bad_data", func() { + request := httptest.NewRequest(http.MethodPut, "/trigger", bytes.NewReader(body)) + request.Header.Add("content-type", "application/json") + request = request.WithContext(middleware.SetContextValueForTest(request.Context(), "metricSourceProvider", allSourceProvider)) + + var returnedErr error = &prometheus.Error{ + Type: prometheus.ErrBadData, + } + + prometheusSrc.EXPECT().Fetch(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, returnedErr) + + _, errRsp := getTriggerFromRequest(request) + So(errRsp, ShouldResemble, api.ErrorInvalidRequest(fmt.Errorf("invalid prometheus targets: %w", returnedErr))) + }) + + Convey("with other types internal server error is returned", func() { + otherTypes := []prometheus.ErrorType{ + prometheus.ErrBadResponse, + prometheus.ErrCanceled, + prometheus.ErrClient, + prometheus.ErrExec, + prometheus.ErrTimeout, + prometheus.ErrServer, + } + + for _, errType := range otherTypes { + request := httptest.NewRequest(http.MethodPut, "/trigger", bytes.NewReader(body)) + request.Header.Add("content-type", "application/json") + request = request.WithContext(middleware.SetContextValueForTest(request.Context(), "metricSourceProvider", allSourceProvider)) + + var returnedErr error = &prometheus.Error{ + Type: errType, + } + + prometheusSrc.EXPECT().Fetch(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, returnedErr) + + _, errRsp := getTriggerFromRequest(request) + So(errRsp, ShouldResemble, api.ErrorInternalServer(returnedErr)) + } + }) + }) + }) } func TestGetMetricTTLByTrigger(t *testing.T) { From cec15c1761004603c55c18158943d0f25797f45f Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Tue, 3 Sep 2024 11:54:20 +0700 Subject: [PATCH 04/12] test: for graphite remote --- api/handler/triggers.go | 4 ++-- api/handler/triggers_test.go | 29 +++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/api/handler/triggers.go b/api/handler/triggers.go index bdac9538c..e26e72b74 100644 --- a/api/handler/triggers.go +++ b/api/handler/triggers.go @@ -174,9 +174,9 @@ func getTriggerFromRequest(request *http.Request) (*dto.Trigger, *api.ErrorRespo case *prometheus.Error: switch typedErr.Type { case prometheus.ErrBadData: - return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid prometheus targets: %w", typedErr)) + return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid prometheus targets: %w", err)) default: - return nil, api.ErrorInternalServer(typedErr) + return nil, api.ErrorInternalServer(err) } default: return nil, api.ErrorInternalServer(err) diff --git a/api/handler/triggers_test.go b/api/handler/triggers_test.go index d998545ec..a7020a321 100644 --- a/api/handler/triggers_test.go +++ b/api/handler/triggers_test.go @@ -5,6 +5,8 @@ import ( "context" "encoding/json" "fmt" + logging "github.com/moira-alert/moira/logging/zerolog_adapter" + "github.com/moira-alert/moira/metric_source/remote" "io" "net/http" "net/http/httptest" @@ -142,7 +144,7 @@ func TestGetTriggerFromRequest(t *testing.T) { }) }) - Convey("With incorrect targets error", t, func() { + Convey("With incorrect targets errors", t, func() { graphiteLocalSrc := mock_metric_source.NewMockMetricSource(mockCtrl) graphiteRemoteSrc := mock_metric_source.NewMockMetricSource(mockCtrl) prometheusSrc := mock_metric_source.NewMockMetricSource(mockCtrl) @@ -180,11 +182,34 @@ func TestGetTriggerFromRequest(t *testing.T) { }, } + Convey("for graphite remote", func() { + triggerDTO.TriggerSource = moira.GraphiteRemote + body, _ := json.Marshal(triggerDTO) + + request := httptest.NewRequest(http.MethodPut, "/trigger", bytes.NewReader(body)) + request.Header.Add("content-type", "application/json") + request = request.WithContext(middleware.SetContextValueForTest(request.Context(), "metricSourceProvider", allSourceProvider)) + + testLogger, _ := logging.GetLogger("Test") + + request = middleware.WithLogEntry(request, middleware.NewLogEntry(testLogger, request)) + + var returnedErr error = remote.ErrRemoteTriggerResponse{ + InternalError: fmt.Errorf(""), + } + + graphiteRemoteSrc.EXPECT().Fetch(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil, returnedErr) + + _, errRsp := getTriggerFromRequest(request) + So(errRsp, ShouldResemble, api.ErrorRemoteServerUnavailable(returnedErr)) + }) + Convey("for prometheus remote", func() { triggerDTO.TriggerSource = moira.PrometheusRemote body, _ := json.Marshal(triggerDTO) - Convey("with error type = bad_data", func() { + Convey("with error type = bad_data got bad request", func() { request := httptest.NewRequest(http.MethodPut, "/trigger", bytes.NewReader(body)) request.Header.Add("content-type", "application/json") request = request.WithContext(middleware.SetContextValueForTest(request.Context(), "metricSourceProvider", allSourceProvider)) From 389994d6b207aa405ae07a2876671470e4d4fc93 Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Tue, 3 Sep 2024 11:56:38 +0700 Subject: [PATCH 05/12] style: use linter --- api/handler/triggers_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api/handler/triggers_test.go b/api/handler/triggers_test.go index a7020a321..f2624d6ef 100644 --- a/api/handler/triggers_test.go +++ b/api/handler/triggers_test.go @@ -5,8 +5,6 @@ import ( "context" "encoding/json" "fmt" - logging "github.com/moira-alert/moira/logging/zerolog_adapter" - "github.com/moira-alert/moira/metric_source/remote" "io" "net/http" "net/http/httptest" @@ -14,6 +12,9 @@ import ( "testing" "time" + logging "github.com/moira-alert/moira/logging/zerolog_adapter" + "github.com/moira-alert/moira/metric_source/remote" + prometheus "github.com/prometheus/client_golang/api/prometheus/v1" "github.com/moira-alert/moira" From e5a223cd2160ee37e7accbf2e69850b105ac4d76 Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Tue, 10 Sep 2024 13:18:43 +0700 Subject: [PATCH 06/12] refactor: change status code returned by `/api/trigger/check` for prometheus errors (except bad data error type) --- api/handler/triggers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/handler/triggers.go b/api/handler/triggers.go index e26e72b74..e25f52876 100644 --- a/api/handler/triggers.go +++ b/api/handler/triggers.go @@ -229,7 +229,7 @@ func triggerCheck(writer http.ResponseWriter, request *http.Request) { render.Render(writer, request, api.ErrorInvalidRequest(fmt.Errorf("invalid prometheus targets: %w", err))) //nolint return default: - render.Render(writer, request, api.ErrorInvalidRequest(err)) //nolint + render.Render(writer, request, api.ErrorInternalServer(err)) //nolint return } default: From d6cd53819fadd344353dc5666e620a54c68898bd Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Wed, 18 Sep 2024 10:58:20 +0700 Subject: [PATCH 07/12] refactor: add debug prints for error handling --- api/handler/triggers.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/api/handler/triggers.go b/api/handler/triggers.go index e25f52876..089b355b1 100644 --- a/api/handler/triggers.go +++ b/api/handler/triggers.go @@ -3,6 +3,7 @@ package handler import ( "encoding/json" "fmt" + "log" "net/http" "net/url" "strconv" @@ -155,6 +156,9 @@ func createTrigger(writer http.ResponseWriter, request *http.Request) { func getTriggerFromRequest(request *http.Request) (*dto.Trigger, *api.ErrorResponse) { trigger := &dto.Trigger{} if err := render.Bind(request, trigger); err != nil { + + log.Printf("err type: %T, msg: %s", err, err) + switch typedErr := err.(type) { // nolint:errorlint case local.ErrParseExpr, local.ErrEvalExpr, local.ErrUnknownFunction: return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid graphite targets: %s", err.Error())) @@ -172,6 +176,9 @@ func getTriggerFromRequest(request *http.Request) (*dto.Trigger, *api.ErrorRespo case *json.UnmarshalTypeError: return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid payload: %s", err.Error())) case *prometheus.Error: + + log.Printf("prom err: type: %s, msg: %s, detail: %s", typedErr.Type, typedErr.Msg, typedErr.Detail) + switch typedErr.Type { case prometheus.ErrBadData: return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid prometheus targets: %w", err)) From 339fd165d8fd86f1c7396440640d6196f0c71a77 Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Wed, 18 Sep 2024 11:56:34 +0700 Subject: [PATCH 08/12] refactor: remove debug prints --- api/handler/triggers.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/api/handler/triggers.go b/api/handler/triggers.go index 089b355b1..e25f52876 100644 --- a/api/handler/triggers.go +++ b/api/handler/triggers.go @@ -3,7 +3,6 @@ package handler import ( "encoding/json" "fmt" - "log" "net/http" "net/url" "strconv" @@ -156,9 +155,6 @@ func createTrigger(writer http.ResponseWriter, request *http.Request) { func getTriggerFromRequest(request *http.Request) (*dto.Trigger, *api.ErrorResponse) { trigger := &dto.Trigger{} if err := render.Bind(request, trigger); err != nil { - - log.Printf("err type: %T, msg: %s", err, err) - switch typedErr := err.(type) { // nolint:errorlint case local.ErrParseExpr, local.ErrEvalExpr, local.ErrUnknownFunction: return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid graphite targets: %s", err.Error())) @@ -176,9 +172,6 @@ func getTriggerFromRequest(request *http.Request) (*dto.Trigger, *api.ErrorRespo case *json.UnmarshalTypeError: return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid payload: %s", err.Error())) case *prometheus.Error: - - log.Printf("prom err: type: %s, msg: %s, detail: %s", typedErr.Type, typedErr.Msg, typedErr.Detail) - switch typedErr.Type { case prometheus.ErrBadData: return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid prometheus targets: %w", err)) From f219c88c592543ff4011bd676befaa419082bb53 Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Wed, 18 Sep 2024 19:27:50 +0700 Subject: [PATCH 09/12] fix: handling error type of prometheus errors --- api/handler/triggers.go | 42 +++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/api/handler/triggers.go b/api/handler/triggers.go index e25f52876..849a3baa6 100644 --- a/api/handler/triggers.go +++ b/api/handler/triggers.go @@ -152,6 +152,32 @@ func createTrigger(writer http.ResponseWriter, request *http.Request) { } } +func errorResponseOnPrometheusError(promErr *prometheus.Error) *api.ErrorResponse { + // In github.com/prometheus/client_golang/api/prometheus/v1 Error has field `Type` + // which can be used to understand "the reason" of error. There are some constants in the lib. + if promErr.Type == prometheus.ErrBadData { + api.ErrorInvalidRequest(fmt.Errorf("invalid prometheus targets: %w", promErr)) + } + + // VictoriaMetrics also supports prometheus api, BUT puts status code into Error.Type. + // So we can't just use constants from prometheus api client lib. + statusCode, err := strconv.ParseInt(string(promErr.Type), 10, 64) + if err != nil { + return api.ErrorInternalServer(promErr) + } + + codes4xxLeadTo500 := map[int64]struct{}{ + http.StatusUnauthorized: {}, + http.StatusForbidden: {}, + } + + if _, leadTo500 := codes4xxLeadTo500[statusCode]; statusCode/100 == 4 && !leadTo500 { + return api.ErrorInvalidRequest(promErr) + } + + return api.ErrorInternalServer(promErr) +} + func getTriggerFromRequest(request *http.Request) (*dto.Trigger, *api.ErrorResponse) { trigger := &dto.Trigger{} if err := render.Bind(request, trigger); err != nil { @@ -172,12 +198,7 @@ func getTriggerFromRequest(request *http.Request) (*dto.Trigger, *api.ErrorRespo case *json.UnmarshalTypeError: return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid payload: %s", err.Error())) case *prometheus.Error: - switch typedErr.Type { - case prometheus.ErrBadData: - return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid prometheus targets: %w", err)) - default: - return nil, api.ErrorInternalServer(err) - } + return nil, errorResponseOnPrometheusError(typedErr) default: return nil, api.ErrorInternalServer(err) } @@ -224,14 +245,7 @@ func triggerCheck(writer http.ResponseWriter, request *http.Request) { // These errors are skipped because if there are error from local source then it will be caught in // dto.TargetVerification and will be explained in detail. case *prometheus.Error: - switch typedErr.Type { - case prometheus.ErrBadData: - render.Render(writer, request, api.ErrorInvalidRequest(fmt.Errorf("invalid prometheus targets: %w", err))) //nolint - return - default: - render.Render(writer, request, api.ErrorInternalServer(err)) //nolint - return - } + render.Render(writer, request, errorResponseOnPrometheusError(typedErr)) default: render.Render(writer, request, api.ErrorInvalidRequest(err)) //nolint return From edfaa20ac193661aa7b181e12faf36810cbd5893 Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Wed, 18 Sep 2024 19:33:51 +0700 Subject: [PATCH 10/12] fix: add return statement, use linter --- api/handler/triggers.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/handler/triggers.go b/api/handler/triggers.go index 849a3baa6..1cf70fdba 100644 --- a/api/handler/triggers.go +++ b/api/handler/triggers.go @@ -156,7 +156,7 @@ func errorResponseOnPrometheusError(promErr *prometheus.Error) *api.ErrorRespons // In github.com/prometheus/client_golang/api/prometheus/v1 Error has field `Type` // which can be used to understand "the reason" of error. There are some constants in the lib. if promErr.Type == prometheus.ErrBadData { - api.ErrorInvalidRequest(fmt.Errorf("invalid prometheus targets: %w", promErr)) + return api.ErrorInvalidRequest(fmt.Errorf("invalid prometheus targets: %w", promErr)) } // VictoriaMetrics also supports prometheus api, BUT puts status code into Error.Type. @@ -245,7 +245,7 @@ func triggerCheck(writer http.ResponseWriter, request *http.Request) { // These errors are skipped because if there are error from local source then it will be caught in // dto.TargetVerification and will be explained in detail. case *prometheus.Error: - render.Render(writer, request, errorResponseOnPrometheusError(typedErr)) + render.Render(writer, request, errorResponseOnPrometheusError(typedErr)) //nolint default: render.Render(writer, request, api.ErrorInvalidRequest(err)) //nolint return From 2854ea1d150bcf1025e49d6c9655186cda2a3d38 Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Tue, 24 Sep 2024 11:46:49 +0700 Subject: [PATCH 11/12] refactor: 4xx code recognition --- api/handler/triggers.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/api/handler/triggers.go b/api/handler/triggers.go index 1cf70fdba..7a4f20443 100644 --- a/api/handler/triggers.go +++ b/api/handler/triggers.go @@ -152,6 +152,10 @@ func createTrigger(writer http.ResponseWriter, request *http.Request) { } } +func is4xxCode(statusCode int) bool { + return statusCode >= 400 && statusCode < 500 +} + func errorResponseOnPrometheusError(promErr *prometheus.Error) *api.ErrorResponse { // In github.com/prometheus/client_golang/api/prometheus/v1 Error has field `Type` // which can be used to understand "the reason" of error. There are some constants in the lib. @@ -171,7 +175,7 @@ func errorResponseOnPrometheusError(promErr *prometheus.Error) *api.ErrorRespons http.StatusForbidden: {}, } - if _, leadTo500 := codes4xxLeadTo500[statusCode]; statusCode/100 == 4 && !leadTo500 { + if _, leadTo500 := codes4xxLeadTo500[statusCode]; is4xxCode(int(statusCode)) && !leadTo500 { return api.ErrorInvalidRequest(promErr) } From 0fa8b259bbb2fbcf3a47c1dc4cceb22b27c7fb9e Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Tue, 24 Sep 2024 12:12:07 +0700 Subject: [PATCH 12/12] fix: use int64 in 4xx checking code func --- api/handler/triggers.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/handler/triggers.go b/api/handler/triggers.go index 7a4f20443..8ee2787a0 100644 --- a/api/handler/triggers.go +++ b/api/handler/triggers.go @@ -152,7 +152,7 @@ func createTrigger(writer http.ResponseWriter, request *http.Request) { } } -func is4xxCode(statusCode int) bool { +func is4xxCode(statusCode int64) bool { return statusCode >= 400 && statusCode < 500 } @@ -175,7 +175,7 @@ func errorResponseOnPrometheusError(promErr *prometheus.Error) *api.ErrorRespons http.StatusForbidden: {}, } - if _, leadTo500 := codes4xxLeadTo500[statusCode]; is4xxCode(int(statusCode)) && !leadTo500 { + if _, leadTo500 := codes4xxLeadTo500[statusCode]; is4xxCode(statusCode) && !leadTo500 { return api.ErrorInvalidRequest(promErr) }