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")