From 040b7d2571c78042329c0af2fa633113e14f0030 Mon Sep 17 00:00:00 2001 From: Marcus Efraimsson Date: Tue, 22 Aug 2023 12:52:24 +0200 Subject: [PATCH] Chore: Add errutils helpers (#73577) Add helpers for the errutil package in favor of errutil.NewBase. --- contribute/backend/errors.md | 16 ++- pkg/api/response/response_test.go | 2 +- pkg/expr/errors.go | 8 +- pkg/infra/grn/errors.go | 2 +- pkg/login/social/errors.go | 8 +- pkg/login/social/github_oauth.go | 4 +- pkg/middleware/loggermw/logger_test.go | 2 +- pkg/plugins/errors.go | 11 +- pkg/services/accesscontrol/models.go | 2 +- pkg/services/annotations/annotations.go | 2 +- pkg/services/authn/authnimpl/service.go | 4 +- .../authn/authnimpl/sync/permission_sync.go | 2 +- .../authn/authnimpl/sync/user_sync.go | 18 ++-- pkg/services/authn/clients/api_key.go | 6 +- pkg/services/authn/clients/basic.go | 2 +- pkg/services/authn/clients/constants.go | 2 +- pkg/services/authn/clients/form.go | 2 +- pkg/services/authn/clients/jwt.go | 6 +- pkg/services/authn/clients/oauth.go | 20 ++-- pkg/services/authn/clients/password.go | 8 +- pkg/services/authn/clients/proxy.go | 6 +- pkg/services/authn/clients/render.go | 2 +- pkg/services/authn/error.go | 10 +- pkg/services/dashboardsnapshots/errors.go | 2 +- pkg/services/datasources/errors.go | 4 +- pkg/services/folder/model.go | 14 +-- pkg/services/guardian/guardian.go | 8 +- pkg/services/oauthserver/errors.go | 6 +- pkg/services/org/model.go | 4 +- pkg/services/preference/model.go | 3 +- .../publicdashboards/models/errors.go | 34 +++--- pkg/services/query/errors.go | 10 +- pkg/services/quota/model.go | 18 ++-- pkg/services/serviceaccounts/models.go | 22 ++-- pkg/services/shorturls/models.go | 10 +- pkg/services/signingkeys/error.go | 6 +- pkg/services/sqlstore/session.go | 2 +- pkg/tsdb/sqleng/sql_engine.go | 2 +- pkg/util/errutil/errhttp/writer.go | 2 +- pkg/util/errutil/errhttp/writer_test.go | 2 +- pkg/util/errutil/errors.go | 102 ++++++++++++++++++ pkg/util/errutil/errors_example_test.go | 6 +- pkg/util/errutil/errors_test.go | 4 +- pkg/util/errutil/template_test.go | 14 ++- pkg/web/context.go | 2 +- 45 files changed, 261 insertions(+), 161 deletions(-) diff --git a/contribute/backend/errors.md b/contribute/backend/errors.md index fed461c46f5..674e3d84305 100644 --- a/contribute/backend/errors.md +++ b/contribute/backend/errors.md @@ -19,8 +19,20 @@ code, and so forth are carried by the error. For a service, declare the different categories of errors that may occur from your service (this corresponds to what you might want to have specific public error messages or their templates for) by globally -constructing variables using the `errutil.NewBase(status, messageID, opts...)` -function. +constructing variables using the `errutil.(status, messageID, opts...)` +functions, e.g. + +- `errutil.NotFound(messageID, opts...)` +- `errutil.BadRequest(messageID, opts...)` +- `errutil.ValidationFailed(messageID, opts...)` +- `errutil.Internal(messageID, opts...)` +- `errutil.Timeout(messageID, opts...)` +- `errutil.Unauthorized(messageID, opts...)` +- `errutil.Forbidden(messageID, opts...)` +- `errutil.TooManyRequests(messageID, opts...)` +- `errutil.NotImplemented(messageID, opts...)` + +Above functions uses `errutil.NewBase(status, messageID, opts...)` under the covers, and that function should in general only be used outside the `errutil` package for `errutil.StatusUnknown`, e.g. when there are no accurate status code available/provided. The status code loosely corresponds to HTTP status codes and provides a default log level for errors to ensure that the request logging is diff --git a/pkg/api/response/response_test.go b/pkg/api/response/response_test.go index a100c42ae48..5d8d10fdfa9 100644 --- a/pkg/api/response/response_test.go +++ b/pkg/api/response/response_test.go @@ -55,7 +55,7 @@ func TestErrors(t *testing.T) { { name: "grafana error with fallback to other error", - err: errutil.NewBase(errutil.StatusTimeout, "thing.timeout").Errorf("whoops"), + err: errutil.Timeout("thing.timeout").Errorf("whoops"), statusCode: http.StatusBadRequest, message: genericErrorMessage, diff --git a/pkg/expr/errors.go b/pkg/expr/errors.go index 6440ab3d64a..7edaea37883 100644 --- a/pkg/expr/errors.go +++ b/pkg/expr/errors.go @@ -6,10 +6,7 @@ import ( "github.com/grafana/grafana/pkg/util/errutil" ) -var ConversionError = errutil.NewBase( - errutil.StatusBadRequest, - "sse.readDataError", -).MustTemplate( +var ConversionError = errutil.BadRequest("sse.readDataError").MustTemplate( "[{{ .Public.refId }}] got error: {{ .Error }}", errutil.WithPublic( "failed to read data from from query {{ .Public.refId }}: {{ .Public.error }}", @@ -28,8 +25,7 @@ func MakeConversionError(refID string, err error) error { return ConversionError.Build(data) } -var QueryError = errutil.NewBase( - errutil.StatusBadRequest, "sse.dataQueryError").MustTemplate( +var QueryError = errutil.BadRequest("sse.dataQueryError").MustTemplate( "failed to execute query [{{ .Public.refId }}]: {{ .Error }}", errutil.WithPublic( "failed to execute query [{{ .Public.refId }}]: {{ .Public.error }}", diff --git a/pkg/infra/grn/errors.go b/pkg/infra/grn/errors.go index e8f1466d343..3fe17a7306c 100644 --- a/pkg/infra/grn/errors.go +++ b/pkg/infra/grn/errors.go @@ -5,5 +5,5 @@ import ( ) var ( - ErrInvalidGRN = errutil.NewBase(errutil.StatusValidationFailed, "grn.InvalidGRN") + ErrInvalidGRN = errutil.ValidationFailed("grn.InvalidGRN") ) diff --git a/pkg/login/social/errors.go b/pkg/login/social/errors.go index 4459eab0186..187c8ec8c80 100644 --- a/pkg/login/social/errors.go +++ b/pkg/login/social/errors.go @@ -10,14 +10,12 @@ var ( ErrIDTokenNotFound = errors.New("id_token not found") ErrEmailNotFound = errors.New("error getting user info: no email found in access token") - errRoleAttributePathNotSet = errutil.NewBase(errutil.StatusBadRequest, - "oauth.role_attribute_path_not_set", + errRoleAttributePathNotSet = errutil.BadRequest("oauth.role_attribute_path_not_set", errutil.WithPublicMessage("Instance role_attribute_path misconfigured, please contact your administrator")) - errRoleAttributeStrictViolation = errutil.NewBase(errutil.StatusBadRequest, - "oauth.role_attribute_strict_violation", + errRoleAttributeStrictViolation = errutil.BadRequest("oauth.role_attribute_strict_violation", errutil.WithPublicMessage("IdP did not return a role attribute, please contact your administrator")) - errInvalidRole = errutil.NewBase(errutil.StatusBadRequest, "oauth.invalid_role", + errInvalidRole = errutil.BadRequest("oauth.invalid_role", errutil.WithPublicMessage("IdP did not return a valid role attribute, please contact your administrator")) ) diff --git a/pkg/login/social/github_oauth.go b/pkg/login/social/github_oauth.go index 50be3a7b2a4..d667dc3fba2 100644 --- a/pkg/login/social/github_oauth.go +++ b/pkg/login/social/github_oauth.go @@ -33,11 +33,11 @@ type GithubTeam struct { } var ( - ErrMissingTeamMembership = errutil.NewBase(errutil.StatusUnauthorized, + ErrMissingTeamMembership = errutil.Unauthorized( "auth.missing_team", errutil.WithPublicMessage( "User is not a member of one of the required teams. Please contact identity provider administrator.")) - ErrMissingOrganizationMembership = errutil.NewBase(errutil.StatusUnauthorized, + ErrMissingOrganizationMembership = errutil.Unauthorized( "auth.missing_organization", errutil.WithPublicMessage( "User is not a member of one of the required organizations. Please contact identity provider administrator.")) diff --git a/pkg/middleware/loggermw/logger_test.go b/pkg/middleware/loggermw/logger_test.go index 639715f3605..bd2a5272bd8 100644 --- a/pkg/middleware/loggermw/logger_test.go +++ b/pkg/middleware/loggermw/logger_test.go @@ -59,7 +59,7 @@ func Test_prepareLog(t *testing.T) { RouterLogging bool } - grafanaFlavoredErr := errutil.NewBase(errutil.StatusNotFound, "test.notFound").Errorf("got error") + grafanaFlavoredErr := errutil.NotFound("test.notFound").Errorf("got error") tests := []struct { name string diff --git a/pkg/plugins/errors.go b/pkg/plugins/errors.go index d7f5b4387b3..371747cb478 100644 --- a/pkg/plugins/errors.go +++ b/pkg/plugins/errors.go @@ -4,13 +4,14 @@ import "github.com/grafana/grafana/pkg/util/errutil" var ( // ErrPluginNotRegistered error returned when a plugin is not registered. - ErrPluginNotRegistered = errutil.NewBase(errutil.StatusNotFound, "plugin.notRegistered") + ErrPluginNotRegistered = errutil.NotFound("plugin.notRegistered") // ErrHealthCheckFailed error returned when a plugin health check failed. - ErrHealthCheckFailed = errutil.NewBase(errutil.StatusInternal, "plugin.failedHealthCheck") + ErrHealthCheckFailed = errutil.Internal("plugin.failedHealthCheck") // ErrPluginUnavailable error returned when a plugin is unavailable. - ErrPluginUnavailable = errutil.NewBase(errutil.StatusInternal, "plugin.unavailable") + ErrPluginUnavailable = errutil.Internal("plugin.unavailable") // ErrMethodNotImplemented error returned when a plugin method is not implemented. - ErrMethodNotImplemented = errutil.NewBase(errutil.StatusNotImplemented, "plugin.notImplemented") + ErrMethodNotImplemented = errutil.NotImplemented("plugin.notImplemented") // ErrPluginDownstreamError error returned when a plugin method is not implemented. - ErrPluginDownstreamError = errutil.NewBase(errutil.StatusInternal, "plugin.downstreamError", errutil.WithPublicMessage("An error occurred within the plugin")) + ErrPluginDownstreamError = errutil.Internal("plugin.downstreamError", + errutil.WithPublicMessage("An error occurred within the plugin")) ) diff --git a/pkg/services/accesscontrol/models.go b/pkg/services/accesscontrol/models.go index 572c903a13c..fd4ca7f3374 100644 --- a/pkg/services/accesscontrol/models.go +++ b/pkg/services/accesscontrol/models.go @@ -13,7 +13,7 @@ import ( "github.com/grafana/grafana/pkg/util/errutil" ) -var ErrInternal = errutil.NewBase(errutil.StatusInternal, "accesscontrol.internal") +var ErrInternal = errutil.Internal("accesscontrol.internal") // RoleRegistration stores a role and its assignments to built-in roles // (Viewer, Editor, Admin, Grafana Admin) diff --git a/pkg/services/annotations/annotations.go b/pkg/services/annotations/annotations.go index 925bebb16cb..08e0b635847 100644 --- a/pkg/services/annotations/annotations.go +++ b/pkg/services/annotations/annotations.go @@ -10,7 +10,7 @@ import ( var ( ErrTimerangeMissing = errors.New("missing timerange") - ErrBaseTagLimitExceeded = errutil.NewBase(errutil.StatusBadRequest, "annotations.tag-limit-exceeded", errutil.WithPublicMessage("Tags length exceeds the maximum allowed.")) + ErrBaseTagLimitExceeded = errutil.BadRequest("annotations.tag-limit-exceeded", errutil.WithPublicMessage("Tags length exceeds the maximum allowed.")) ) //go:generate mockery --name Repository --structname FakeAnnotationsRepo --inpackage --filename annotations_repository_mock.go diff --git a/pkg/services/authn/authnimpl/service.go b/pkg/services/authn/authnimpl/service.go index 3561db9b5d0..963212d08af 100644 --- a/pkg/services/authn/authnimpl/service.go +++ b/pkg/services/authn/authnimpl/service.go @@ -43,8 +43,8 @@ const ( ) var ( - errCantAuthenticateReq = errutil.NewBase(errutil.StatusUnauthorized, "auth.unauthorized") - errDisabledIdentity = errutil.NewBase(errutil.StatusUnauthorized, "identity.disabled") + errCantAuthenticateReq = errutil.Unauthorized("auth.unauthorized") + errDisabledIdentity = errutil.Unauthorized("identity.disabled") ) // make sure service implements authn.Service interface diff --git a/pkg/services/authn/authnimpl/sync/permission_sync.go b/pkg/services/authn/authnimpl/sync/permission_sync.go index ba297713de7..13e48f2d942 100644 --- a/pkg/services/authn/authnimpl/sync/permission_sync.go +++ b/pkg/services/authn/authnimpl/sync/permission_sync.go @@ -10,7 +10,7 @@ import ( ) var ( - errSyncPermissionsForbidden = errutil.NewBase(errutil.StatusForbidden, "permissions.sync.forbidden") + errSyncPermissionsForbidden = errutil.Forbidden("permissions.sync.forbidden") ) func ProvidePermissionsSync(acService accesscontrol.Service) *PermissionsSync { diff --git a/pkg/services/authn/authnimpl/sync/user_sync.go b/pkg/services/authn/authnimpl/sync/user_sync.go index 7094c96f2fc..3ed8a95198b 100644 --- a/pkg/services/authn/authnimpl/sync/user_sync.go +++ b/pkg/services/authn/authnimpl/sync/user_sync.go @@ -14,33 +14,27 @@ import ( ) var ( - errUserSignupDisabled = errutil.NewBase( - errutil.StatusUnauthorized, + errUserSignupDisabled = errutil.Unauthorized( "user.sync.signup-disabled", errutil.WithPublicMessage("Sign up is disabled"), ) - errSyncUserForbidden = errutil.NewBase( - errutil.StatusForbidden, + errSyncUserForbidden = errutil.Forbidden( "user.sync.forbidden", errutil.WithPublicMessage("User sync forbidden"), ) - errSyncUserInternal = errutil.NewBase( - errutil.StatusInternal, + errSyncUserInternal = errutil.Internal( "user.sync.internal", errutil.WithPublicMessage("User sync failed"), ) - errUserProtection = errutil.NewBase( - errutil.StatusForbidden, + errUserProtection = errutil.Forbidden( "user.sync.protected-role", errutil.WithPublicMessage("Unable to sync due to protected role"), ) - errFetchingSignedInUser = errutil.NewBase( - errutil.StatusInternal, + errFetchingSignedInUser = errutil.Internal( "user.sync.fetch", errutil.WithPublicMessage("Insufficient information to authenticate user"), ) - errFetchingSignedInUserNotFound = errutil.NewBase( - errutil.StatusUnauthorized, + errFetchingSignedInUserNotFound = errutil.Unauthorized( "user.sync.fetch-not-found", errutil.WithPublicMessage("User not found"), ) diff --git a/pkg/services/authn/clients/api_key.go b/pkg/services/authn/clients/api_key.go index 23a8bac4a44..c2df44ef78e 100644 --- a/pkg/services/authn/clients/api_key.go +++ b/pkg/services/authn/clients/api_key.go @@ -19,9 +19,9 @@ import ( ) var ( - errAPIKeyInvalid = errutil.NewBase(errutil.StatusUnauthorized, "api-key.invalid", errutil.WithPublicMessage("Invalid API key")) - errAPIKeyExpired = errutil.NewBase(errutil.StatusUnauthorized, "api-key.expired", errutil.WithPublicMessage("Expired API key")) - errAPIKeyRevoked = errutil.NewBase(errutil.StatusUnauthorized, "api-key.revoked", errutil.WithPublicMessage("Revoked API key")) + errAPIKeyInvalid = errutil.Unauthorized("api-key.invalid", errutil.WithPublicMessage("Invalid API key")) + errAPIKeyExpired = errutil.Unauthorized("api-key.expired", errutil.WithPublicMessage("Expired API key")) + errAPIKeyRevoked = errutil.Unauthorized("api-key.revoked", errutil.WithPublicMessage("Revoked API key")) ) var _ authn.HookClient = new(APIKey) diff --git a/pkg/services/authn/clients/basic.go b/pkg/services/authn/clients/basic.go index cca31b6458d..bda9f3c1ed5 100644 --- a/pkg/services/authn/clients/basic.go +++ b/pkg/services/authn/clients/basic.go @@ -9,7 +9,7 @@ import ( ) var ( - errDecodingBasicAuthHeader = errutil.NewBase(errutil.StatusBadRequest, "basic-auth.invalid-header", errutil.WithPublicMessage("Invalid Basic Auth Header")) + errDecodingBasicAuthHeader = errutil.BadRequest("basic-auth.invalid-header", errutil.WithPublicMessage("Invalid Basic Auth Header")) ) var _ authn.ContextAwareClient = new(Basic) diff --git a/pkg/services/authn/clients/constants.go b/pkg/services/authn/clients/constants.go index 0d8734c61fa..f2fee7a82d8 100644 --- a/pkg/services/authn/clients/constants.go +++ b/pkg/services/authn/clients/constants.go @@ -9,5 +9,5 @@ const ( ) var ( - errIdentityNotFound = errutil.NewBase(errutil.StatusNotFound, "identity.not-found") + errIdentityNotFound = errutil.NotFound("identity.not-found") ) diff --git a/pkg/services/authn/clients/form.go b/pkg/services/authn/clients/form.go index 2195892cca3..a16a884a35c 100644 --- a/pkg/services/authn/clients/form.go +++ b/pkg/services/authn/clients/form.go @@ -9,7 +9,7 @@ import ( ) var ( - errBadForm = errutil.NewBase(errutil.StatusBadRequest, "form-auth.invalid", errutil.WithPublicMessage("bad login data")) + errBadForm = errutil.BadRequest("form-auth.invalid", errutil.WithPublicMessage("bad login data")) ) var _ authn.Client = new(Form) diff --git a/pkg/services/authn/clients/jwt.go b/pkg/services/authn/clients/jwt.go index 0f5fad2d64c..c183f846cab 100644 --- a/pkg/services/authn/clients/jwt.go +++ b/pkg/services/authn/clients/jwt.go @@ -24,11 +24,11 @@ const authQueryParamName = "auth_token" var _ authn.ContextAwareClient = new(JWT) var ( - errJWTInvalid = errutil.NewBase(errutil.StatusUnauthorized, + errJWTInvalid = errutil.Unauthorized( "jwt.invalid", errutil.WithPublicMessage("Failed to verify JWT")) - errJWTMissingClaim = errutil.NewBase(errutil.StatusUnauthorized, + errJWTMissingClaim = errutil.Unauthorized( "jwt.missing_claim", errutil.WithPublicMessage("Missing mandatory claim in JWT")) - errJWTInvalidRole = errutil.NewBase(errutil.StatusForbidden, + errJWTInvalidRole = errutil.Forbidden( "jwt.invalid_role", errutil.WithPublicMessage("Invalid Role in claim")) ) diff --git a/pkg/services/authn/clients/oauth.go b/pkg/services/authn/clients/oauth.go index d3483af89af..e2b39229478 100644 --- a/pkg/services/authn/clients/oauth.go +++ b/pkg/services/authn/clients/oauth.go @@ -35,22 +35,22 @@ const ( ) var ( - errOAuthGenPKCE = errutil.NewBase(errutil.StatusInternal, "auth.oauth.pkce.internal", errutil.WithPublicMessage("An internal error occurred")) - errOAuthMissingPKCE = errutil.NewBase(errutil.StatusBadRequest, "auth.oauth.pkce.missing", errutil.WithPublicMessage("Missing required pkce cookie")) + errOAuthGenPKCE = errutil.Internal("auth.oauth.pkce.internal", errutil.WithPublicMessage("An internal error occurred")) + errOAuthMissingPKCE = errutil.BadRequest("auth.oauth.pkce.missing", errutil.WithPublicMessage("Missing required pkce cookie")) - errOAuthGenState = errutil.NewBase(errutil.StatusInternal, "auth.oauth.state.internal", errutil.WithPublicMessage("An internal error occurred")) - errOAuthMissingState = errutil.NewBase(errutil.StatusBadRequest, "auth.oauth.state.missing", errutil.WithPublicMessage("Missing saved oauth state")) - errOAuthInvalidState = errutil.NewBase(errutil.StatusUnauthorized, "auth.oauth.state.invalid", errutil.WithPublicMessage("Provided state does not match stored state")) + errOAuthGenState = errutil.Internal("auth.oauth.state.internal", errutil.WithPublicMessage("An internal error occurred")) + errOAuthMissingState = errutil.BadRequest("auth.oauth.state.missing", errutil.WithPublicMessage("Missing saved oauth state")) + errOAuthInvalidState = errutil.Unauthorized("auth.oauth.state.invalid", errutil.WithPublicMessage("Provided state does not match stored state")) - errOAuthTokenExchange = errutil.NewBase(errutil.StatusInternal, "auth.oauth.token.exchange", errutil.WithPublicMessage("Failed to get token from provider")) - errOAuthUserInfo = errutil.NewBase(errutil.StatusInternal, "auth.oauth.userinfo.error") + errOAuthTokenExchange = errutil.Internal("auth.oauth.token.exchange", errutil.WithPublicMessage("Failed to get token from provider")) + errOAuthUserInfo = errutil.Internal("auth.oauth.userinfo.error") - errOAuthMissingRequiredEmail = errutil.NewBase(errutil.StatusUnauthorized, "auth.oauth.email.missing", errutil.WithPublicMessage("Provider didn't return an email address")) - errOAuthEmailNotAllowed = errutil.NewBase(errutil.StatusUnauthorized, "auth.oauth.email.not-allowed", errutil.WithPublicMessage("Required email domain not fulfilled")) + errOAuthMissingRequiredEmail = errutil.Unauthorized("auth.oauth.email.missing", errutil.WithPublicMessage("Provider didn't return an email address")) + errOAuthEmailNotAllowed = errutil.Unauthorized("auth.oauth.email.not-allowed", errutil.WithPublicMessage("Required email domain not fulfilled")) ) func fromSocialErr(err *social.Error) error { - return errutil.NewBase(errutil.StatusUnauthorized, "auth.oauth.userinfo.failed", errutil.WithPublicMessage(err.Error())).Errorf("%w", err) + return errutil.Unauthorized("auth.oauth.userinfo.failed", errutil.WithPublicMessage(err.Error())).Errorf("%w", err) } var _ authn.RedirectClient = new(OAuth) diff --git a/pkg/services/authn/clients/password.go b/pkg/services/authn/clients/password.go index 9d0efe769dc..8af6e0794ce 100644 --- a/pkg/services/authn/clients/password.go +++ b/pkg/services/authn/clients/password.go @@ -12,10 +12,10 @@ import ( ) var ( - errEmptyPassword = errutil.NewBase(errutil.StatusUnauthorized, "password-auth.empty", errutil.WithPublicMessage("Invalid username or password")) - errPasswordAuthFailed = errutil.NewBase(errutil.StatusUnauthorized, "password-auth.failed", errutil.WithPublicMessage("Invalid username or password")) - errInvalidPassword = errutil.NewBase(errutil.StatusUnauthorized, "password-auth.invalid", errutil.WithPublicMessage("Invalid password or username")) - errLoginAttemptBlocked = errutil.NewBase(errutil.StatusUnauthorized, "login-attempt.blocked", errutil.WithPublicMessage("Invalid username or password")) + errEmptyPassword = errutil.Unauthorized("password-auth.empty", errutil.WithPublicMessage("Invalid username or password")) + errPasswordAuthFailed = errutil.Unauthorized("password-auth.failed", errutil.WithPublicMessage("Invalid username or password")) + errInvalidPassword = errutil.Unauthorized("password-auth.invalid", errutil.WithPublicMessage("Invalid password or username")) + errLoginAttemptBlocked = errutil.Unauthorized("login-attempt.blocked", errutil.WithPublicMessage("Invalid username or password")) ) var _ authn.PasswordClient = new(Password) diff --git a/pkg/services/authn/clients/proxy.go b/pkg/services/authn/clients/proxy.go index c79f45f8583..d6ada1116af 100644 --- a/pkg/services/authn/clients/proxy.go +++ b/pkg/services/authn/clients/proxy.go @@ -32,9 +32,9 @@ const ( var proxyFields = [...]string{proxyFieldName, proxyFieldEmail, proxyFieldLogin, proxyFieldRole, proxyFieldGroups} var ( - errNotAcceptedIP = errutil.NewBase(errutil.StatusUnauthorized, "auth-proxy.invalid-ip") - errEmptyProxyHeader = errutil.NewBase(errutil.StatusUnauthorized, "auth-proxy.empty-header") - errInvalidProxyHeader = errutil.NewBase(errutil.StatusInternal, "auth-proxy.invalid-proxy-header") + errNotAcceptedIP = errutil.Unauthorized("auth-proxy.invalid-ip") + errEmptyProxyHeader = errutil.Unauthorized("auth-proxy.empty-header") + errInvalidProxyHeader = errutil.Internal("auth-proxy.invalid-proxy-header") ) var ( diff --git a/pkg/services/authn/clients/render.go b/pkg/services/authn/clients/render.go index 5e37372f826..8a8649bd036 100644 --- a/pkg/services/authn/clients/render.go +++ b/pkg/services/authn/clients/render.go @@ -13,7 +13,7 @@ import ( ) var ( - errInvalidRenderKey = errutil.NewBase(errutil.StatusUnauthorized, "render-auth.invalid-key", errutil.WithPublicMessage("Invalid Render Key")) + errInvalidRenderKey = errutil.Unauthorized("render-auth.invalid-key", errutil.WithPublicMessage("Invalid Render Key")) ) const ( diff --git a/pkg/services/authn/error.go b/pkg/services/authn/error.go index 613f5947837..33fbdba1320 100644 --- a/pkg/services/authn/error.go +++ b/pkg/services/authn/error.go @@ -3,9 +3,9 @@ package authn import "github.com/grafana/grafana/pkg/util/errutil" var ( - ErrTokenNeedsRotation = errutil.NewBase(errutil.StatusUnauthorized, "session.token.rotate") - ErrUnsupportedClient = errutil.NewBase(errutil.StatusBadRequest, "auth.client.unsupported") - ErrClientNotConfigured = errutil.NewBase(errutil.StatusBadRequest, "auth.client.notConfigured") - ErrUnsupportedIdentity = errutil.NewBase(errutil.StatusNotImplemented, "auth.identity.unsupported") - ErrExpiredAccessToken = errutil.NewBase(errutil.StatusUnauthorized, "oauth.expired-token", errutil.WithPublicMessage("OAuth access token expired")) + ErrTokenNeedsRotation = errutil.Unauthorized("session.token.rotate") + ErrUnsupportedClient = errutil.BadRequest("auth.client.unsupported") + ErrClientNotConfigured = errutil.BadRequest("auth.client.notConfigured") + ErrUnsupportedIdentity = errutil.NotImplemented("auth.identity.unsupported") + ErrExpiredAccessToken = errutil.Unauthorized("oauth.expired-token", errutil.WithPublicMessage("OAuth access token expired")) ) diff --git a/pkg/services/dashboardsnapshots/errors.go b/pkg/services/dashboardsnapshots/errors.go index 1a6e07c9d86..e2750d610a6 100644 --- a/pkg/services/dashboardsnapshots/errors.go +++ b/pkg/services/dashboardsnapshots/errors.go @@ -4,4 +4,4 @@ import ( "github.com/grafana/grafana/pkg/util/errutil" ) -var ErrBaseNotFound = errutil.NewBase(errutil.StatusNotFound, "dashboardsnapshots.not-found", errutil.WithPublicMessage("Snapshot not found")) +var ErrBaseNotFound = errutil.NotFound("dashboardsnapshots.not-found", errutil.WithPublicMessage("Snapshot not found")) diff --git a/pkg/services/datasources/errors.go b/pkg/services/datasources/errors.go index b6e8759cddc..b13156d5849 100644 --- a/pkg/services/datasources/errors.go +++ b/pkg/services/datasources/errors.go @@ -15,6 +15,6 @@ var ( ErrDataSourceFailedGenerateUniqueUid = errors.New("failed to generate unique datasource ID") ErrDataSourceIdentifierNotSet = errors.New("unique identifier and org id are needed to be able to get or delete a datasource") ErrDatasourceIsReadOnly = errors.New("data source is readonly, can only be updated from configuration") - ErrDataSourceNameInvalid = errutil.NewBase(errutil.StatusValidationFailed, "datasource.nameInvalid", errutil.WithPublicMessage("Invalid datasource name.")) - ErrDataSourceURLInvalid = errutil.NewBase(errutil.StatusValidationFailed, "datasource.urlInvalid", errutil.WithPublicMessage("Invalid datasource url.")) + ErrDataSourceNameInvalid = errutil.ValidationFailed("datasource.nameInvalid", errutil.WithPublicMessage("Invalid datasource name.")) + ErrDataSourceURLInvalid = errutil.ValidationFailed("datasource.urlInvalid", errutil.WithPublicMessage("Invalid datasource url.")) ) diff --git a/pkg/services/folder/model.go b/pkg/services/folder/model.go index e96a8b795c5..cc157c3d05a 100644 --- a/pkg/services/folder/model.go +++ b/pkg/services/folder/model.go @@ -10,12 +10,12 @@ import ( "github.com/grafana/grafana/pkg/util/errutil" ) -var ErrMaximumDepthReached = errutil.NewBase(errutil.StatusBadRequest, "folder.maximum-depth-reached", errutil.WithPublicMessage("Maximum nested folder depth reached")) -var ErrBadRequest = errutil.NewBase(errutil.StatusBadRequest, "folder.bad-request") -var ErrDatabaseError = errutil.NewBase(errutil.StatusInternal, "folder.database-error") -var ErrInternal = errutil.NewBase(errutil.StatusInternal, "folder.internal") -var ErrCircularReference = errutil.NewBase(errutil.StatusBadRequest, "folder.circular-reference", errutil.WithPublicMessage("Circular reference detected")) -var ErrTargetRegistrySrvConflict = errutil.NewBase(errutil.StatusInternal, "folder.target-registry-srv-conflict") +var ErrMaximumDepthReached = errutil.BadRequest("folder.maximum-depth-reached", errutil.WithPublicMessage("Maximum nested folder depth reached")) +var ErrBadRequest = errutil.BadRequest("folder.bad-request") +var ErrDatabaseError = errutil.Internal("folder.database-error") +var ErrInternal = errutil.Internal("folder.internal") +var ErrCircularReference = errutil.BadRequest("folder.circular-reference", errutil.WithPublicMessage("Circular reference detected")) +var ErrTargetRegistrySrvConflict = errutil.Internal("folder.target-registry-srv-conflict") const ( GeneralFolderUID = "general" @@ -23,7 +23,7 @@ const ( MaxNestedFolderDepth = 8 ) -var ErrFolderNotFound = errutil.NewBase(errutil.StatusNotFound, "folder.notFound") +var ErrFolderNotFound = errutil.NotFound("folder.notFound") type Folder struct { ID int64 `xorm:"pk autoincr 'id'"` diff --git a/pkg/services/guardian/guardian.go b/pkg/services/guardian/guardian.go index 9e810899f61..66e34b4a7a1 100644 --- a/pkg/services/guardian/guardian.go +++ b/pkg/services/guardian/guardian.go @@ -18,10 +18,10 @@ import ( var ( ErrGuardianPermissionExists = errors.New("permission already exists") ErrGuardianOverride = errors.New("you can only override a permission to be higher") - ErrGuardianGetDashboardFailure = errutil.NewBase(errutil.StatusInternal, "guardian.getDashboardFailure", errutil.WithPublicMessage("Failed to get dashboard")) - ErrGuardianGetFolderFailure = errutil.NewBase(errutil.StatusInternal, "guardian.getFolderFailure", errutil.WithPublicMessage("Failed to get folder")) - ErrGuardianDashboardNotFound = errutil.NewBase(errutil.StatusNotFound, "guardian.dashboardNotFound") - ErrGuardianFolderNotFound = errutil.NewBase(errutil.StatusNotFound, "guardian.folderNotFound") + ErrGuardianGetDashboardFailure = errutil.Internal("guardian.getDashboardFailure", errutil.WithPublicMessage("Failed to get dashboard")) + ErrGuardianGetFolderFailure = errutil.Internal("guardian.getFolderFailure", errutil.WithPublicMessage("Failed to get folder")) + ErrGuardianDashboardNotFound = errutil.NotFound("guardian.dashboardNotFound") + ErrGuardianFolderNotFound = errutil.NotFound("guardian.folderNotFound") ) // DashboardGuardian to be used for guard against operations without access on dashboard and acl diff --git a/pkg/services/oauthserver/errors.go b/pkg/services/oauthserver/errors.go index b7a1b68153a..43d395b4d49 100644 --- a/pkg/services/oauthserver/errors.go +++ b/pkg/services/oauthserver/errors.go @@ -11,16 +11,16 @@ var ( ) var ( - ErrClientRequiredID = errutil.NewBase(errutil.StatusBadRequest, + ErrClientRequiredID = errutil.BadRequest( "oauthserver.required-client-id", errutil.WithPublicMessage("client ID is required")).Errorf("Client ID is required") - ErrClientRequiredName = errutil.NewBase(errutil.StatusBadRequest, + ErrClientRequiredName = errutil.BadRequest( "oauthserver.required-client-name", errutil.WithPublicMessage("client name is required")).Errorf("Client name is required") ) func ErrClientNotFound(clientID string) error { - return errutil.NewBase(errutil.StatusNotFound, + return errutil.NotFound( ErrClientNotFoundMessageID, errutil.WithPublicMessage(fmt.Sprintf("Client '%s' not found", clientID))). Errorf("client '%s' not found", clientID) diff --git a/pkg/services/org/model.go b/pkg/services/org/model.go index 6837ed97dc6..d7802c183db 100644 --- a/pkg/services/org/model.go +++ b/pkg/services/org/model.go @@ -16,8 +16,8 @@ var ( ErrLastOrgAdmin = errors.New("cannot remove last organization admin") ErrOrgUserNotFound = errors.New("cannot find the organization user") ErrOrgUserAlreadyAdded = errors.New("user is already added to organization") - ErrOrgNotFound = errutil.NewBase(errutil.StatusNotFound, "org.notFound", errutil.WithPublicMessage("organization not found")) - ErrCannotChangeRoleForExternallySyncedUser = errutil.NewBase(errutil.StatusForbidden, "org.externallySynced", errutil.WithPublicMessage("cannot change role for externally synced user")) + ErrOrgNotFound = errutil.NotFound("org.notFound", errutil.WithPublicMessage("organization not found")) + ErrCannotChangeRoleForExternallySyncedUser = errutil.Forbidden("org.externallySynced", errutil.WithPublicMessage("cannot change role for externally synced user")) ) type Org struct { diff --git a/pkg/services/preference/model.go b/pkg/services/preference/model.go index fd5407be21f..eeb58e06ae3 100644 --- a/pkg/services/preference/model.go +++ b/pkg/services/preference/model.go @@ -12,8 +12,7 @@ import ( ) var ErrPrefNotFound = errors.New("preference not found") -var ErrUnknownCookieType = errutil.NewBase( - errutil.StatusBadRequest, +var ErrUnknownCookieType = errutil.BadRequest( "preferences.unknownCookieType", errutil.WithPublicMessage("Got an unknown cookie preference type. Expected a set containing one or more of 'functional', 'performance', or 'analytics'}"), ) diff --git a/pkg/services/publicdashboards/models/errors.go b/pkg/services/publicdashboards/models/errors.go index b73217201cb..58909ea9934 100644 --- a/pkg/services/publicdashboards/models/errors.go +++ b/pkg/services/publicdashboards/models/errors.go @@ -3,24 +3,24 @@ package models import "github.com/grafana/grafana/pkg/util/errutil" var ( - ErrInternalServerError = errutil.NewBase(errutil.StatusInternal, "publicdashboards.internalServerError", errutil.WithPublicMessage("Internal server error")) + ErrInternalServerError = errutil.Internal("publicdashboards.internalServerError", errutil.WithPublicMessage("Internal server error")) - ErrPublicDashboardNotFound = errutil.NewBase(errutil.StatusNotFound, "publicdashboards.notFound", errutil.WithPublicMessage("Public dashboard not found")) - ErrDashboardNotFound = errutil.NewBase(errutil.StatusNotFound, "publicdashboards.dashboardNotFound", errutil.WithPublicMessage("Dashboard not found")) - ErrPanelNotFound = errutil.NewBase(errutil.StatusNotFound, "publicdashboards.panelNotFound", errutil.WithPublicMessage("Public dashboard panel not found")) + ErrPublicDashboardNotFound = errutil.NotFound("publicdashboards.notFound", errutil.WithPublicMessage("Public dashboard not found")) + ErrDashboardNotFound = errutil.NotFound("publicdashboards.dashboardNotFound", errutil.WithPublicMessage("Dashboard not found")) + ErrPanelNotFound = errutil.NotFound("publicdashboards.panelNotFound", errutil.WithPublicMessage("Public dashboard panel not found")) - ErrBadRequest = errutil.NewBase(errutil.StatusBadRequest, "publicdashboards.badRequest") - ErrPanelQueriesNotFound = errutil.NewBase(errutil.StatusBadRequest, "publicdashboards.panelQueriesNotFound", errutil.WithPublicMessage("Failed to extract queries from panel")) - ErrInvalidAccessToken = errutil.NewBase(errutil.StatusBadRequest, "publicdashboards.invalidAccessToken", errutil.WithPublicMessage("Invalid access token")) - ErrInvalidPanelId = errutil.NewBase(errutil.StatusBadRequest, "publicdashboards.invalidPanelId", errutil.WithPublicMessage("Invalid panel id")) - ErrInvalidUid = errutil.NewBase(errutil.StatusBadRequest, "publicdashboards.invalidUid", errutil.WithPublicMessage("Invalid Uid")) - ErrPublicDashboardIdentifierNotSet = errutil.NewBase(errutil.StatusBadRequest, "publicdashboards.identifierNotSet", errutil.WithPublicMessage("No Uid for public dashboard specified")) - ErrPublicDashboardHasTemplateVariables = errutil.NewBase(errutil.StatusBadRequest, "publicdashboards.hasTemplateVariables", errutil.WithPublicMessage("Public dashboard has template variables")) - ErrInvalidInterval = errutil.NewBase(errutil.StatusBadRequest, "publicdashboards.invalidInterval", errutil.WithPublicMessage("intervalMS should be greater than 0")) - ErrInvalidMaxDataPoints = errutil.NewBase(errutil.StatusBadRequest, "publicdashboards.maxDataPoints", errutil.WithPublicMessage("maxDataPoints should be greater than 0")) - ErrInvalidTimeRange = errutil.NewBase(errutil.StatusBadRequest, "publicdashboards.invalidTimeRange", errutil.WithPublicMessage("Invalid time range")) - ErrInvalidShareType = errutil.NewBase(errutil.StatusBadRequest, "publicdashboards.invalidShareType", errutil.WithPublicMessage("Invalid share type")) - ErrDashboardIsPublic = errutil.NewBase(errutil.StatusBadRequest, "publicdashboards.dashboardIsPublic", errutil.WithPublicMessage("Dashboard is already public")) + ErrBadRequest = errutil.BadRequest("publicdashboards.badRequest") + ErrPanelQueriesNotFound = errutil.BadRequest("publicdashboards.panelQueriesNotFound", errutil.WithPublicMessage("Failed to extract queries from panel")) + ErrInvalidAccessToken = errutil.BadRequest("publicdashboards.invalidAccessToken", errutil.WithPublicMessage("Invalid access token")) + ErrInvalidPanelId = errutil.BadRequest("publicdashboards.invalidPanelId", errutil.WithPublicMessage("Invalid panel id")) + ErrInvalidUid = errutil.BadRequest("publicdashboards.invalidUid", errutil.WithPublicMessage("Invalid Uid")) + ErrPublicDashboardIdentifierNotSet = errutil.BadRequest("publicdashboards.identifierNotSet", errutil.WithPublicMessage("No Uid for public dashboard specified")) + ErrPublicDashboardHasTemplateVariables = errutil.BadRequest("publicdashboards.hasTemplateVariables", errutil.WithPublicMessage("Public dashboard has template variables")) + ErrInvalidInterval = errutil.BadRequest("publicdashboards.invalidInterval", errutil.WithPublicMessage("intervalMS should be greater than 0")) + ErrInvalidMaxDataPoints = errutil.BadRequest("publicdashboards.maxDataPoints", errutil.WithPublicMessage("maxDataPoints should be greater than 0")) + ErrInvalidTimeRange = errutil.BadRequest("publicdashboards.invalidTimeRange", errutil.WithPublicMessage("Invalid time range")) + ErrInvalidShareType = errutil.BadRequest("publicdashboards.invalidShareType", errutil.WithPublicMessage("Invalid share type")) + ErrDashboardIsPublic = errutil.BadRequest("publicdashboards.dashboardIsPublic", errutil.WithPublicMessage("Dashboard is already public")) - ErrPublicDashboardNotEnabled = errutil.NewBase(errutil.StatusForbidden, "publicdashboards.notEnabled", errutil.WithPublicMessage("Public dashboard paused")) + ErrPublicDashboardNotEnabled = errutil.Forbidden("publicdashboards.notEnabled", errutil.WithPublicMessage("Public dashboard paused")) ) diff --git a/pkg/services/query/errors.go b/pkg/services/query/errors.go index fbb3a50e1a7..1aa41403b6d 100644 --- a/pkg/services/query/errors.go +++ b/pkg/services/query/errors.go @@ -5,9 +5,9 @@ import ( ) var ( - ErrNoQueriesFound = errutil.NewBase(errutil.StatusBadRequest, "query.noQueries", errutil.WithPublicMessage("No queries found")).Errorf("no queries found") - ErrInvalidDatasourceID = errutil.NewBase(errutil.StatusBadRequest, "query.invalidDatasourceId", errutil.WithPublicMessage("Query does not contain a valid data source identifier")).Errorf("invalid data source identifier") - ErrMissingDataSourceInfo = errutil.NewBase(errutil.StatusBadRequest, "query.missingDataSourceInfo").MustTemplate("query missing datasource info: {{ .Public.RefId }}", errutil.WithPublic("Query {{ .Public.RefId }} is missing datasource information")) - ErrQueryParamMismatch = errutil.NewBase(errutil.StatusBadRequest, "query.headerMismatch", errutil.WithPublicMessage("The request headers point to a different plugin than is defined in the request body")).Errorf("plugin header/body mismatch") - ErrDuplicateRefId = errutil.NewBase(errutil.StatusBadRequest, "query.duplicateRefId", errutil.WithPublicMessage("Multiple queries using the same RefId is not allowed ")).Errorf("multiple queries using the same RefId is not allowed") + ErrNoQueriesFound = errutil.BadRequest("query.noQueries", errutil.WithPublicMessage("No queries found")).Errorf("no queries found") + ErrInvalidDatasourceID = errutil.BadRequest("query.invalidDatasourceId", errutil.WithPublicMessage("Query does not contain a valid data source identifier")).Errorf("invalid data source identifier") + ErrMissingDataSourceInfo = errutil.BadRequest("query.missingDataSourceInfo").MustTemplate("query missing datasource info: {{ .Public.RefId }}", errutil.WithPublic("Query {{ .Public.RefId }} is missing datasource information")) + ErrQueryParamMismatch = errutil.BadRequest("query.headerMismatch", errutil.WithPublicMessage("The request headers point to a different plugin than is defined in the request body")).Errorf("plugin header/body mismatch") + ErrDuplicateRefId = errutil.BadRequest("query.duplicateRefId", errutil.WithPublicMessage("Multiple queries using the same RefId is not allowed ")).Errorf("multiple queries using the same RefId is not allowed") ) diff --git a/pkg/services/quota/model.go b/pkg/services/quota/model.go index c9915bebb0c..aa9022d3d2d 100644 --- a/pkg/services/quota/model.go +++ b/pkg/services/quota/model.go @@ -8,15 +8,15 @@ import ( "github.com/grafana/grafana/pkg/util/errutil" ) -var ErrBadRequest = errutil.NewBase(errutil.StatusBadRequest, "quota.bad-request") -var ErrInvalidTargetSrv = errutil.NewBase(errutil.StatusBadRequest, "quota.invalid-target") -var ErrInvalidScope = errutil.NewBase(errutil.StatusBadRequest, "quota.invalid-scope") -var ErrFailedToGetScope = errutil.NewBase(errutil.StatusInternal, "quota.failed-get-scope") -var ErrInvalidTarget = errutil.NewBase(errutil.StatusInternal, "quota.invalid-target-table") -var ErrUsageFoundForTarget = errutil.NewBase(errutil.StatusNotFound, "quota.missing-target-usage") -var ErrTargetSrvConflict = errutil.NewBase(errutil.StatusBadRequest, "quota.target-srv-conflict") -var ErrDisabled = errutil.NewBase(errutil.StatusForbidden, "quota.disabled", errutil.WithPublicMessage("Quotas not enabled")) -var ErrInvalidTagFormat = errutil.NewBase(errutil.StatusInternal, "quota.invalid-invalid-tag-format") +var ErrBadRequest = errutil.BadRequest("quota.bad-request") +var ErrInvalidTargetSrv = errutil.BadRequest("quota.invalid-target") +var ErrInvalidScope = errutil.BadRequest("quota.invalid-scope") +var ErrFailedToGetScope = errutil.Internal("quota.failed-get-scope") +var ErrInvalidTarget = errutil.Internal("quota.invalid-target-table") +var ErrUsageFoundForTarget = errutil.NotFound("quota.missing-target-usage") +var ErrTargetSrvConflict = errutil.BadRequest("quota.target-srv-conflict") +var ErrDisabled = errutil.Forbidden("quota.disabled", errutil.WithPublicMessage("Quotas not enabled")) +var ErrInvalidTagFormat = errutil.Internal("quota.invalid-invalid-tag-format") type ScopeParameters struct { OrgID int64 diff --git a/pkg/services/serviceaccounts/models.go b/pkg/services/serviceaccounts/models.go index fb6af518cba..a01f2d0554a 100644 --- a/pkg/services/serviceaccounts/models.go +++ b/pkg/services/serviceaccounts/models.go @@ -24,17 +24,17 @@ const ( ) var ( - ErrServiceAccountNotFound = errutil.NewBase(errutil.StatusNotFound, "serviceaccounts.ErrNotFound", errutil.WithPublicMessage("service account not found")) - ErrServiceAccountInvalidRole = errutil.NewBase(errutil.StatusBadRequest, "serviceaccounts.ErrInvalidRoleSpecified", errutil.WithPublicMessage("invalid role specified")) - ErrServiceAccountRolePrivilegeDenied = errutil.NewBase(errutil.StatusForbidden, "serviceaccounts.ErrRoleForbidden", errutil.WithPublicMessage("can not assign a role higher than user's role")) - ErrServiceAccountInvalidOrgID = errutil.NewBase(errutil.StatusBadRequest, "serviceaccounts.ErrInvalidOrgId", errutil.WithPublicMessage("invalid org id specified")) - ErrServiceAccountInvalidID = errutil.NewBase(errutil.StatusBadRequest, "serviceaccounts.ErrInvalidId", errutil.WithPublicMessage("invalid service account id specified")) - ErrServiceAccountInvalidAPIKeyID = errutil.NewBase(errutil.StatusBadRequest, "serviceaccounts.ErrInvalidAPIKeyId", errutil.WithPublicMessage("invalid api key id specified")) - ErrServiceAccountInvalidTokenID = errutil.NewBase(errutil.StatusBadRequest, "serviceaccounts.ErrInvalidTokenId", errutil.WithPublicMessage("invalid service account token id specified")) - ErrServiceAccountAlreadyExists = errutil.NewBase(errutil.StatusBadRequest, "serviceaccounts.ErrAlreadyExists", errutil.WithPublicMessage("service account already exists")) - ErrServiceAccountTokenNotFound = errutil.NewBase(errutil.StatusNotFound, "serviceaccounts.ErrTokenNotFound", errutil.WithPublicMessage("service account token not found")) - ErrInvalidTokenExpiration = errutil.NewBase(errutil.StatusValidationFailed, "serviceaccounts.ErrInvalidInput", errutil.WithPublicMessage("invalid SecondsToLive value")) - ErrDuplicateToken = errutil.NewBase(errutil.StatusBadRequest, "serviceaccounts.ErrTokenAlreadyExists", errutil.WithPublicMessage("service account token with given name already exists in the organization")) + ErrServiceAccountNotFound = errutil.NotFound("serviceaccounts.ErrNotFound", errutil.WithPublicMessage("service account not found")) + ErrServiceAccountInvalidRole = errutil.BadRequest("serviceaccounts.ErrInvalidRoleSpecified", errutil.WithPublicMessage("invalid role specified")) + ErrServiceAccountRolePrivilegeDenied = errutil.Forbidden("serviceaccounts.ErrRoleForbidden", errutil.WithPublicMessage("can not assign a role higher than user's role")) + ErrServiceAccountInvalidOrgID = errutil.BadRequest("serviceaccounts.ErrInvalidOrgId", errutil.WithPublicMessage("invalid org id specified")) + ErrServiceAccountInvalidID = errutil.BadRequest("serviceaccounts.ErrInvalidId", errutil.WithPublicMessage("invalid service account id specified")) + ErrServiceAccountInvalidAPIKeyID = errutil.BadRequest("serviceaccounts.ErrInvalidAPIKeyId", errutil.WithPublicMessage("invalid api key id specified")) + ErrServiceAccountInvalidTokenID = errutil.BadRequest("serviceaccounts.ErrInvalidTokenId", errutil.WithPublicMessage("invalid service account token id specified")) + ErrServiceAccountAlreadyExists = errutil.BadRequest("serviceaccounts.ErrAlreadyExists", errutil.WithPublicMessage("service account already exists")) + ErrServiceAccountTokenNotFound = errutil.NotFound("serviceaccounts.ErrTokenNotFound", errutil.WithPublicMessage("service account token not found")) + ErrInvalidTokenExpiration = errutil.ValidationFailed("serviceaccounts.ErrInvalidInput", errutil.WithPublicMessage("invalid SecondsToLive value")) + ErrDuplicateToken = errutil.BadRequest("serviceaccounts.ErrTokenAlreadyExists", errutil.WithPublicMessage("service account token with given name already exists in the organization")) ) type MigrationResult struct { diff --git a/pkg/services/shorturls/models.go b/pkg/services/shorturls/models.go index c6cb840c40c..37355552fa3 100644 --- a/pkg/services/shorturls/models.go +++ b/pkg/services/shorturls/models.go @@ -7,11 +7,11 @@ import ( ) var ( - ErrShortURLBadRequest = errutil.NewBase(errutil.StatusBadRequest, "shorturl.bad-request") - ErrShortURLNotFound = errutil.NewBase(errutil.StatusNotFound, "shorturl.not-found") - ErrShortURLAbsolutePath = errutil.NewBase(errutil.StatusValidationFailed, "shorturl.absolute-path", errutil.WithPublicMessage("Path should be relative")) - ErrShortURLInvalidPath = errutil.NewBase(errutil.StatusValidationFailed, "shorturl.invalid-path", errutil.WithPublicMessage("Invalid short URL path")) - ErrShortURLInternal = errutil.NewBase(errutil.StatusInternal, "shorturl.internal") + ErrShortURLBadRequest = errutil.BadRequest("shorturl.bad-request") + ErrShortURLNotFound = errutil.NotFound("shorturl.not-found") + ErrShortURLAbsolutePath = errutil.ValidationFailed("shorturl.absolute-path", errutil.WithPublicMessage("Path should be relative")) + ErrShortURLInvalidPath = errutil.ValidationFailed("shorturl.invalid-path", errutil.WithPublicMessage("Invalid short URL path")) + ErrShortURLInternal = errutil.Internal("shorturl.internal") ) type ShortUrl struct { diff --git a/pkg/services/signingkeys/error.go b/pkg/services/signingkeys/error.go index 2ef529f00fe..8dfe65dd972 100644 --- a/pkg/services/signingkeys/error.go +++ b/pkg/services/signingkeys/error.go @@ -3,7 +3,7 @@ package signingkeys import "github.com/grafana/grafana/pkg/util/errutil" var ( - ErrSigningKeyNotFound = errutil.NewBase(errutil.StatusNotFound, "signingkeys.keyNotFound") - ErrSigningKeyAlreadyExists = errutil.NewBase(errutil.StatusBadRequest, "signingkeys.keyAlreadyExists") - ErrKeyGenerationFailed = errutil.NewBase(errutil.StatusInternal, "signingkeys.keyGenerationFailed") + ErrSigningKeyNotFound = errutil.NotFound("signingkeys.keyNotFound") + ErrSigningKeyAlreadyExists = errutil.BadRequest("signingkeys.keyAlreadyExists") + ErrKeyGenerationFailed = errutil.Internal("signingkeys.keyGenerationFailed") ) diff --git a/pkg/services/sqlstore/session.go b/pkg/services/sqlstore/session.go index 999f490c19d..ccfac05e7a9 100644 --- a/pkg/services/sqlstore/session.go +++ b/pkg/services/sqlstore/session.go @@ -19,7 +19,7 @@ import ( ) var sessionLogger = log.New("sqlstore.session") -var ErrMaximumRetriesReached = errutil.NewBase(errutil.StatusInternal, "sqlstore.max-retries-reached") +var ErrMaximumRetriesReached = errutil.Internal("sqlstore.max-retries-reached") type DBSession struct { *xorm.Session diff --git a/pkg/tsdb/sqleng/sql_engine.go b/pkg/tsdb/sqleng/sql_engine.go index ab63c7b452a..0ccf62ccec9 100644 --- a/pkg/tsdb/sqleng/sql_engine.go +++ b/pkg/tsdb/sqleng/sql_engine.go @@ -31,7 +31,7 @@ var XormDriverMu sync.RWMutex // MetaKeyExecutedQueryString is the key where the executed query should get stored const MetaKeyExecutedQueryString = "executedQueryString" -var ErrConnectionFailed = errutil.NewBase(errutil.StatusInternal, "sqleng.connectionError") +var ErrConnectionFailed = errutil.Internal("sqleng.connectionError") // SQLMacroEngine interpolates macros into sql. It takes in the Query to have access to query context and // timeRange to be able to generate queries that use from and to. diff --git a/pkg/util/errutil/errhttp/writer.go b/pkg/util/errutil/errhttp/writer.go index 5bbd9aede2e..08de5720c68 100644 --- a/pkg/util/errutil/errhttp/writer.go +++ b/pkg/util/errutil/errhttp/writer.go @@ -11,7 +11,7 @@ import ( "github.com/grafana/grafana/pkg/util/errutil" ) -var ErrNonGrafanaError = errutil.NewBase(errutil.StatusInternal, "core.MalformedError") +var ErrNonGrafanaError = errutil.Internal("core.MalformedError") var defaultLogger = log.New("requestErrors") // ErrorOptions is a container for functional options passed to [Write]. diff --git a/pkg/util/errutil/errhttp/writer_test.go b/pkg/util/errutil/errhttp/writer_test.go index edc554bd74d..00737ebf711 100644 --- a/pkg/util/errutil/errhttp/writer_test.go +++ b/pkg/util/errutil/errhttp/writer_test.go @@ -14,7 +14,7 @@ import ( func TestWrite(t *testing.T) { ctx := context.Background() const msgID = "test.thisIsExpected" - base := errutil.NewBase(errutil.StatusTimeout, msgID) + base := errutil.Timeout(msgID) handler := func(writer http.ResponseWriter, request *http.Request) { Write(ctx, base.Errorf("got expected error"), writer) } diff --git a/pkg/util/errutil/errors.go b/pkg/util/errutil/errors.go index 09b833acfe5..8dc81542a50 100644 --- a/pkg/util/errutil/errors.go +++ b/pkg/util/errutil/errors.go @@ -41,6 +41,108 @@ func NewBase(reason StatusReason, msgID string, opts ...BaseOpt) Base { return b } +// NotFound initializes a new [Base] error with reason StatusNotFound +// that is used to construct [Error]. The msgID is passed to the caller +// to serve as the base for user facing error messages. +// +// msgID should be structured as component.errorBrief, for example +// +// folder.notFound +// plugin.notRegistered +func NotFound(msgID string, opts ...BaseOpt) Base { + return NewBase(StatusNotFound, msgID, opts...) +} + +// BadRequest initializes a new [Base] error with reason StatusBadRequest +// that is used to construct [Error]. The msgID is passed to the caller +// to serve as the base for user facing error messages. +// +// msgID should be structured as component.errorBrief, for example +// +// query.invalidDatasourceId +// sse.dataQueryError +func BadRequest(msgID string, opts ...BaseOpt) Base { + return NewBase(StatusBadRequest, msgID, opts...) +} + +// ValidationFailed initializes a new [Base] error with reason StatusValidationFailed +// that is used to construct [Error]. The msgID is passed to the caller +// to serve as the base for user facing error messages. +// +// msgID should be structured as component.errorBrief, for example +// +// datasource.nameInvalid +// datasource.urlInvalid +// serviceaccounts.errInvalidInput +func ValidationFailed(msgID string, opts ...BaseOpt) Base { + return NewBase(StatusValidationFailed, msgID, opts...) +} + +// Internal initializes a new [Base] error with reason StatusInternal +// that is used to construct [Error]. The msgID is passed to the caller +// to serve as the base for user facing error messages. +// +// msgID should be structured as component.errorBrief, for example +// +// sqleng.connectionError +// plugin.downstreamError +func Internal(msgID string, opts ...BaseOpt) Base { + return NewBase(StatusInternal, msgID, opts...) +} + +// Timeout initializes a new [Base] error with reason StatusTimeout. +// +// area.timeout +func Timeout(msgID string, opts ...BaseOpt) Base { + return NewBase(StatusTimeout, msgID, opts...) +} + +// Unauthorized initializes a new [Base] error with reason StatusUnauthorized +// that is used to construct [Error]. The msgID is passed to the caller +// to serve as the base for user facing error messages. +// +// msgID should be structured as component.errorBrief, for example +// +// auth.unauthorized +func Unauthorized(msgID string, opts ...BaseOpt) Base { + return NewBase(StatusUnauthorized, msgID, opts...) +} + +// Forbidden initializes a new [Base] error with reason StatusForbidden +// that is used to construct [Error]. The msgID is passed to the caller +// to serve as the base for user facing error messages. +// +// msgID should be structured as component.errorBrief, for example +// +// quota.disabled +// user.sync.forbidden +func Forbidden(msgID string, opts ...BaseOpt) Base { + return NewBase(StatusForbidden, msgID, opts...) +} + +// TooManyRequests initializes a new [Base] error with reason StatusTooManyRequests +// that is used to construct [Error]. The msgID is passed to the caller +// to serve as the base for user facing error messages. +// +// msgID should be structured as component.errorBrief, for example +// +// area.tooManyRequests +func TooManyRequests(msgID string, opts ...BaseOpt) Base { + return NewBase(StatusTooManyRequests, msgID, opts...) +} + +// NotImplemented initializes a new [Base] error with reason StatusNotImplemented +// that is used to construct [Error]. The msgID is passed to the caller +// to serve as the base for user facing error messages. +// +// msgID should be structured as component.errorBrief, for example +// +// plugin.notImplemented +// auth.identity.unsupported +func NotImplemented(msgID string, opts ...BaseOpt) Base { + return NewBase(StatusNotImplemented, msgID, opts...) +} + type BaseOpt func(Base) Base // WithLogLevel sets a custom log level for all errors instantiated from diff --git a/pkg/util/errutil/errors_example_test.go b/pkg/util/errutil/errors_example_test.go index da06df3196c..14f35e9b5b9 100644 --- a/pkg/util/errutil/errors_example_test.go +++ b/pkg/util/errutil/errors_example_test.go @@ -15,9 +15,9 @@ var ( // same error message for the frontend statically within the // package. - errAbsPath = errutil.NewBase(errutil.StatusBadRequest, "shorturl.absolutePath") - errInvalidPath = errutil.NewBase(errutil.StatusBadRequest, "shorturl.invalidPath") - errUnexpected = errutil.NewBase(errutil.StatusInternal, "shorturl.unexpected") + errAbsPath = errutil.BadRequest("shorturl.absolutePath") + errInvalidPath = errutil.BadRequest("shorturl.invalidPath") + errUnexpected = errutil.Internal("shorturl.unexpected") ) func Example() { diff --git a/pkg/util/errutil/errors_test.go b/pkg/util/errutil/errors_test.go index ac3292d5b91..5e49827a32b 100644 --- a/pkg/util/errutil/errors_test.go +++ b/pkg/util/errutil/errors_test.go @@ -10,8 +10,8 @@ import ( ) func TestBase_Is(t *testing.T) { - baseNotFound := NewBase(StatusNotFound, "test.notFound") - baseInternal := NewBase(StatusInternal, "test.internal") + baseNotFound := NotFound("test.notFound") + baseInternal := Internal("test.internal") tests := []struct { Base Base diff --git a/pkg/util/errutil/template_test.go b/pkg/util/errutil/template_test.go index 4eaa3ec0285..5cb8df322ec 100644 --- a/pkg/util/errutil/template_test.go +++ b/pkg/util/errutil/template_test.go @@ -11,7 +11,7 @@ import ( ) func TestTemplate(t *testing.T) { - tmpl := errutil.NewBase(errutil.StatusInternal, "template.sampleError").MustTemplate("[{{ .Public.user }}] got error: {{ .Error }}") + tmpl := errutil.Internal("template.sampleError").MustTemplate("[{{ .Public.user }}] got error: {{ .Error }}") err := tmpl.Build(errutil.TemplateData{ Public: map[string]interface{}{ "user": "grot the bot", @@ -31,7 +31,7 @@ func TestTemplate(t *testing.T) { func ExampleTemplate() { // Initialization, this is typically done on a package or global // level. - var tmpl = errutil.NewBase(errutil.StatusInternal, "template.sampleError").MustTemplate("[{{ .Public.user }}] got error: {{ .Error }}") + var tmpl = errutil.Internal("template.sampleError").MustTemplate("[{{ .Public.user }}] got error: {{ .Error }}") // Construct an error based on the template. err := tmpl.Build(errutil.TemplateData{ @@ -50,12 +50,10 @@ func ExampleTemplate() { func ExampleTemplate_public() { // Initialization, this is typically done on a package or global // level. - var tmpl = errutil. - NewBase(errutil.StatusInternal, "template.sampleError"). - MustTemplate( - "[{{ .Public.user }}] got error: {{ .Error }}", - errutil.WithPublic("Oh, no, error for {{ .Public.user }}"), - ) + var tmpl = errutil.Internal("template.sampleError").MustTemplate( + "[{{ .Public.user }}] got error: {{ .Error }}", + errutil.WithPublic("Oh, no, error for {{ .Public.user }}"), + ) // Construct an error based on the template. //nolint:errorlint diff --git a/pkg/web/context.go b/pkg/web/context.go index 5fd3eaa398f..ef7afd7b49f 100644 --- a/pkg/web/context.go +++ b/pkg/web/context.go @@ -40,7 +40,7 @@ type Context struct { template *template.Template } -var errMissingWrite = errutil.NewBase(errutil.StatusInternal, "web.missingWrite") +var errMissingWrite = errutil.Internal("web.missingWrite") func (ctx *Context) run() { h := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))