From ed69ccfd5d678e1b1bce095a0500fd1ce44b287a Mon Sep 17 00:00:00 2001 From: Roman Loginov Date: Wed, 25 Dec 2024 16:09:03 +0300 Subject: [PATCH] [#187] Add handling quota limit reached error The Access Denied status may be received from APE due to exceeding the quota. In this situation, you need to return the appropriate status code. Signed-off-by: Roman Loginov --- internal/handler/handler.go | 2 ++ internal/handler/utils.go | 3 +++ internal/service/frostfs/frostfs.go | 3 +++ internal/service/frostfs/frostfs_test.go | 11 +++++++++++ 4 files changed, 19 insertions(+) diff --git a/internal/handler/handler.go b/internal/handler/handler.go index 470f494..ed90163 100644 --- a/internal/handler/handler.go +++ b/internal/handler/handler.go @@ -139,6 +139,8 @@ var ( ErrAccessDenied = errors.New("access denied") // ErrGatewayTimeout is returned from FrostFS in case of timeout, deadline exceeded etc. ErrGatewayTimeout = errors.New("gateway timeout") + // ErrQuotaLimitReached is returned from FrostFS in case of quota exceeded. + ErrQuotaLimitReached = errors.New("quota limit reached") ) // FrostFS represents virtual connection to FrostFS network. diff --git a/internal/handler/utils.go b/internal/handler/utils.go index 8ebcecd..5d9cb60 100644 --- a/internal/handler/utils.go +++ b/internal/handler/utils.go @@ -106,6 +106,9 @@ func formErrorResponse(message string, err error) (int, string) { case errors.Is(err, ErrGatewayTimeout): statusCode = fasthttp.StatusBadGateway errMsg = err.Error() + case errors.Is(err, ErrQuotaLimitReached): + statusCode = fasthttp.StatusConflict + errMsg = err.Error() case client.IsErrObjectNotFound(err) || client.IsErrContainerNotFound(err): statusCode = fasthttp.StatusNotFound errMsg = "Not Found" diff --git a/internal/service/frostfs/frostfs.go b/internal/service/frostfs/frostfs.go index c7e56a4..f50d1d3 100644 --- a/internal/service/frostfs/frostfs.go +++ b/internal/service/frostfs/frostfs.go @@ -205,6 +205,9 @@ func handleObjectError(msg string, err error) error { } if reason, ok := IsErrObjectAccessDenied(err); ok { + if strings.Contains(reason, "limit reached") { + return fmt.Errorf("%s: %w: %s", msg, handler.ErrQuotaLimitReached, reason) + } return fmt.Errorf("%s: %w: %s", msg, handler.ErrAccessDenied, reason) } diff --git a/internal/service/frostfs/frostfs_test.go b/internal/service/frostfs/frostfs_test.go index 78c8f38..c49d4db 100644 --- a/internal/service/frostfs/frostfs_test.go +++ b/internal/service/frostfs/frostfs_test.go @@ -33,6 +33,17 @@ func TestHandleObjectError(t *testing.T) { require.Contains(t, err.Error(), msg) }) + t.Run("access denied - quota reached", func(t *testing.T) { + reason := "Quota limit reached" + inputErr := new(apistatus.ObjectAccessDenied) + inputErr.WriteReason(reason) + + err := handleObjectError(msg, inputErr) + require.ErrorIs(t, err, handler.ErrQuotaLimitReached) + require.Contains(t, err.Error(), reason) + require.Contains(t, err.Error(), msg) + }) + t.Run("simple timeout", func(t *testing.T) { inputErr := errors.New("timeout")