mirror of
https://github.com/grafana/grafana.git
synced 2025-12-20 19:44:55 +08:00
Compare commits
3 Commits
docs/add-t
...
emil/20221
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f46046255 | ||
|
|
be1984cd36 | ||
|
|
dbbae9f944 |
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/models/errs"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
@@ -17,7 +18,7 @@ import (
|
||||
func (hs *HTTPServer) createShortURL(c *models.ReqContext) response.Response {
|
||||
cmd := dtos.CreateShortURLCmd{}
|
||||
if err := web.Bind(c.Req, &cmd); err != nil {
|
||||
return response.Err(models.ErrShortURLBadRequest.Errorf("bad request data: %w", err))
|
||||
return response.Err(errs.ErrShorturlBadRequest.Errorf("bad request data: %w", err))
|
||||
}
|
||||
hs.log.Debug("Received request to create short URL", "path", cmd.Path)
|
||||
shortURL, err := hs.ShortURLService.CreateShortURL(c.Req.Context(), c.SignedInUser, cmd.Path)
|
||||
@@ -45,7 +46,7 @@ func (hs *HTTPServer) redirectFromShortURL(c *models.ReqContext) {
|
||||
|
||||
shortURL, err := hs.ShortURLService.GetShortURLByUID(c.Req.Context(), c.SignedInUser, shortURLUID)
|
||||
if err != nil {
|
||||
if models.ErrShortURLNotFound.Is(err) {
|
||||
if errs.ErrShorturlNotFound.Is(err) {
|
||||
hs.log.Debug("Not redirecting short URL since not found")
|
||||
return
|
||||
}
|
||||
|
||||
7
pkg/models/errs/Makefile
Normal file
7
pkg/models/errs/Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
SRCS=$(wildcard *.hcl)
|
||||
OBJS=$(SRCS:.hcl=.gen.go)
|
||||
|
||||
all: $(OBJS)
|
||||
|
||||
%.gen.go: %.hcl errutil.tmpl
|
||||
eish generate --source=$< --template=./errutil.tmpl --package=errs > $@
|
||||
39
pkg/models/errs/errutil.tmpl
Normal file
39
pkg/models/errs/errutil.tmpl
Normal file
@@ -0,0 +1,39 @@
|
||||
// Code generated by Errata. DO NOT EDIT.
|
||||
// Errata Schema Version: {{ SchemaVersion }}
|
||||
// Grafana errors schema version: 1
|
||||
// Hash: {{ Hash }}
|
||||
package {{ Package }}
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/util/errutil"
|
||||
)
|
||||
|
||||
var (
|
||||
{%- for code, error in Errors sorted %}
|
||||
Err{{ code | constantize }} = errutil.NewBase(
|
||||
{%- if error.Cause %}
|
||||
errutil.Status{{ error.Cause }},
|
||||
{%- else %}
|
||||
errutil.StatusMissing, // Fixme: Set 'cause' to one of the statuses defined as "errutil.Status*".
|
||||
{%- endif %}
|
||||
{{ code | stringformat:"%q" }},
|
||||
{%- if error.Message && !error.Labels.template %}
|
||||
errutil.WithPublicMessage(`{{ error.Message | escape_backtick -}}`),
|
||||
{%- endif %}
|
||||
{%- if error.Labels.severity %}
|
||||
errutil.WithLogLevel(errutil.Level{{ error.Labels.severity | capfirst }}),
|
||||
{%- endif %}
|
||||
{%- if error.Guide %}
|
||||
errutil.WithGuide(`{{ error.Guide | escape_backtick -}}`),
|
||||
{%- endif %}
|
||||
){%- if error.Labels.template %}.MustTemplate(
|
||||
{%- if error.Labels.logMessage %}
|
||||
`{{ error.Labels.logMessage | escape_backtick -}}`,
|
||||
errutil.WithPublic(`{{ error.Message | escape_backtick -}}`),
|
||||
{%- else %}
|
||||
`{{ error.Message | escape_backtick -}}`,
|
||||
errutil.WithPublicFromLog(),
|
||||
{%- endif %}
|
||||
){%- endif %}
|
||||
{%- endfor %}
|
||||
)
|
||||
3
pkg/models/errs/gen.go
Normal file
3
pkg/models/errs/gen.go
Normal file
@@ -0,0 +1,3 @@
|
||||
package errs
|
||||
|
||||
//go:generate make all
|
||||
42
pkg/models/errs/shorturl.gen.go
Normal file
42
pkg/models/errs/shorturl.gen.go
Normal file
@@ -0,0 +1,42 @@
|
||||
// Code generated by Errata. DO NOT EDIT.
|
||||
// Errata Schema Version: 0.1
|
||||
// Grafana errors schema version: 1
|
||||
// Hash: 41882bb99ce21663b620467357c47a06
|
||||
package errs
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/util/errutil"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrShorturlAbsolutePath = errutil.NewBase(
|
||||
errutil.StatusValidationFailed,
|
||||
"shorturl.absolutePath",
|
||||
errutil.WithPublicMessage(`Path should be relative`),
|
||||
errutil.WithGuide(`Try removing any prefixing ` + "`" + `/` + "`" + ` to your path.`),
|
||||
)
|
||||
ErrShorturlBadRequest = errutil.NewBase(
|
||||
errutil.StatusBadRequest,
|
||||
"shorturl.badRequest",
|
||||
errutil.WithPublicMessage(`Bad request`),
|
||||
)
|
||||
ErrShorturlInternal = errutil.NewBase(
|
||||
errutil.StatusInternal,
|
||||
"shorturl.internal",
|
||||
errutil.WithPublicMessage(`Internal server error`),
|
||||
)
|
||||
ErrShorturlInvalidPath = errutil.NewBase(
|
||||
errutil.StatusValidationFailed,
|
||||
"shorturl.invalidPath",
|
||||
errutil.WithPublicMessage(`Invalid short URL path`),
|
||||
errutil.WithGuide(`There is something wrong with the path you've submitted. It might
|
||||
contain unsupported characters or path-components .. to move up in the
|
||||
hierarchy, which is not supported by the shorturl service.
|
||||
`),
|
||||
)
|
||||
ErrShorturlNotFound = errutil.NewBase(
|
||||
errutil.StatusNotFound,
|
||||
"shorturl.notFound",
|
||||
errutil.WithPublicMessage(`Could not find the specified short URL`),
|
||||
)
|
||||
)
|
||||
32
pkg/models/errs/shorturl.hcl
Normal file
32
pkg/models/errs/shorturl.hcl
Normal file
@@ -0,0 +1,32 @@
|
||||
version = "0.1"
|
||||
|
||||
error "shorturl.badRequest" {
|
||||
message = "Bad request"
|
||||
cause = "BadRequest"
|
||||
}
|
||||
|
||||
error "shorturl.notFound" {
|
||||
message = "Could not find the specified short URL"
|
||||
cause = "NotFound"
|
||||
}
|
||||
|
||||
error "shorturl.absolutePath" {
|
||||
message = "Path should be relative"
|
||||
cause = "ValidationFailed"
|
||||
guide = "Try removing any prefixing `/` to your path."
|
||||
}
|
||||
|
||||
error "shorturl.invalidPath" {
|
||||
message = "Invalid short URL path"
|
||||
cause = "ValidationFailed"
|
||||
guide = <<EOF
|
||||
There is something wrong with the path you've submitted. It might
|
||||
contain unsupported characters or path-components .. to move up in the
|
||||
hierarchy, which is not supported by the shorturl service.
|
||||
EOF
|
||||
}
|
||||
|
||||
error "shorturl.internal" {
|
||||
message = "Internal server error"
|
||||
cause = "Internal"
|
||||
}
|
||||
@@ -2,16 +2,6 @@ package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/util/errutil"
|
||||
)
|
||||
|
||||
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")
|
||||
)
|
||||
|
||||
type ShortUrl struct {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/models/errs"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
@@ -39,7 +40,7 @@ func (s ShortURLService) GetShortURLByUID(ctx context.Context, user *user.Signed
|
||||
return err
|
||||
}
|
||||
if !exists {
|
||||
return models.ErrShortURLNotFound.Errorf("short URL not found")
|
||||
return errs.ErrShorturlNotFound.Errorf("short URL not found")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -67,10 +68,10 @@ func (s ShortURLService) CreateShortURL(ctx context.Context, user *user.SignedIn
|
||||
relPath = strings.TrimSpace(relPath)
|
||||
|
||||
if path.IsAbs(relPath) {
|
||||
return nil, models.ErrShortURLAbsolutePath.Errorf("expected relative path: %s", relPath)
|
||||
return nil, errs.ErrShorturlAbsolutePath.Errorf("expected relative path: %s", relPath)
|
||||
}
|
||||
if strings.Contains(relPath, "../") {
|
||||
return nil, models.ErrShortURLInvalidPath.Errorf("path cannot contain '../': %s", relPath)
|
||||
return nil, errs.ErrShorturlInvalidPath.Errorf("path cannot contain '../': %s", relPath)
|
||||
}
|
||||
|
||||
now := time.Now().Unix()
|
||||
@@ -87,7 +88,7 @@ func (s ShortURLService) CreateShortURL(ctx context.Context, user *user.SignedIn
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return nil, models.ErrShortURLInternal.Errorf("failed to insert shorturl: %w", err)
|
||||
return nil, errs.ErrShorturlInternal.Errorf("failed to insert shorturl: %w", err)
|
||||
}
|
||||
|
||||
return &shortURL, nil
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models/errs"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
@@ -81,7 +83,7 @@ func TestShortURLService(t *testing.T) {
|
||||
|
||||
shortURL, err := service.GetShortURLByUID(context.Background(), user, "testnotfounduid")
|
||||
require.Error(t, err)
|
||||
require.True(t, models.ErrShortURLNotFound.Is(err))
|
||||
require.True(t, errs.ErrShorturlNotFound.Is(err))
|
||||
require.Nil(t, shortURL)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ type Base struct {
|
||||
messageID string
|
||||
publicMessage string
|
||||
logLevel LogLevel
|
||||
guide string
|
||||
}
|
||||
|
||||
// NewBase initializes a [Base] that is used to construct [Error].
|
||||
@@ -54,6 +55,17 @@ func WithLogLevel(lvl LogLevel) BaseOpt {
|
||||
}
|
||||
}
|
||||
|
||||
// WithGuide adds a longer text intended to support a user to resolve
|
||||
// the error.
|
||||
//
|
||||
// Used as a functional option to [NewBase].
|
||||
func WithGuide(guide string) BaseOpt {
|
||||
return func(b Base) Base {
|
||||
b.guide = guide
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
// WithPublicMessage sets the default public message that will be used
|
||||
// for errors based on this [Base].
|
||||
//
|
||||
@@ -171,6 +183,9 @@ type Error struct {
|
||||
PublicPayload map[string]interface{}
|
||||
// LogLevel provides a suggested level of logging for the error.
|
||||
LogLevel LogLevel
|
||||
// Guide is a longer text intended to support a user to resolve
|
||||
// the error.
|
||||
Guide string
|
||||
}
|
||||
|
||||
// MarshalJSON returns an error, we do not want raw [Error]s being
|
||||
@@ -229,6 +244,7 @@ type PublicError struct {
|
||||
MessageID string `json:"messageId"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Extra map[string]interface{} `json:"extra,omitempty"`
|
||||
Guide string `json:"guide,omitempty"`
|
||||
}
|
||||
|
||||
// Public returns a subset of the error with non-sensitive information
|
||||
@@ -249,5 +265,6 @@ func (e Error) Public() PublicError {
|
||||
MessageID: e.MessageID,
|
||||
Message: message,
|
||||
Extra: e.PublicPayload,
|
||||
Guide: e.Guide,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user