Chore: Add errutils helpers (#73577)

Add helpers for the errutil package in favor of errutil.NewBase.
This commit is contained in:
Marcus Efraimsson
2023-08-22 12:52:24 +02:00
committed by GitHub
parent 1cc226e689
commit 040b7d2571
45 changed files with 261 additions and 161 deletions

View File

@@ -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>(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

View File

@@ -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,

View File

@@ -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 }}",

View File

@@ -5,5 +5,5 @@ import (
)
var (
ErrInvalidGRN = errutil.NewBase(errutil.StatusValidationFailed, "grn.InvalidGRN")
ErrInvalidGRN = errutil.ValidationFailed("grn.InvalidGRN")
)

View File

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

View File

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

View File

@@ -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

View File

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

View File

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

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

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

View File

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

View File

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

View File

@@ -9,5 +9,5 @@ const (
)
var (
errIdentityNotFound = errutil.NewBase(errutil.StatusNotFound, "identity.not-found")
errIdentityNotFound = errutil.NotFound("identity.not-found")
)

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 (

View File

@@ -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 (

View File

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

View File

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

View File

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

View File

@@ -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'"`

View File

@@ -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

View File

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

View File

@@ -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 {

View File

@@ -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'}"),
)

View File

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

View File

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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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 {

View File

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

View File

@@ -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

View File

@@ -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.

View File

@@ -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].

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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() {

View File

@@ -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

View File

@@ -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

View File

@@ -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) {}))