mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Add error options for rendering to return errors on failure (#48864)
This commit is contained in:
parent
7b9929fffe
commit
897db011eb
@ -41,6 +41,7 @@ func getRequestTimeout(opt TimeoutOpts) time.Duration {
|
|||||||
type Opts struct {
|
type Opts struct {
|
||||||
TimeoutOpts
|
TimeoutOpts
|
||||||
AuthOpts
|
AuthOpts
|
||||||
|
ErrorOpts
|
||||||
Width int
|
Width int
|
||||||
Height int
|
Height int
|
||||||
Path string
|
Path string
|
||||||
@ -52,6 +53,15 @@ type Opts struct {
|
|||||||
Theme models.Theme
|
Theme models.Theme
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ErrorOpts struct {
|
||||||
|
// ErrorConcurrentLimitReached returns an ErrConcurrentLimitReached
|
||||||
|
// error instead of a rendering limit exceeded image.
|
||||||
|
ErrorConcurrentLimitReached bool
|
||||||
|
// ErrorRenderUnavailable returns an ErrRunderUnavailable error
|
||||||
|
// instead of a rendering unavailable image.
|
||||||
|
ErrorRenderUnavailable bool
|
||||||
|
}
|
||||||
|
|
||||||
type CSVOpts struct {
|
type CSVOpts struct {
|
||||||
TimeoutOpts
|
TimeoutOpts
|
||||||
AuthOpts
|
AuthOpts
|
||||||
|
@ -235,6 +235,9 @@ func (rs *RenderingService) Render(ctx context.Context, opts Opts, session Sessi
|
|||||||
func (rs *RenderingService) render(ctx context.Context, opts Opts, renderKeyProvider renderKeyProvider) (*RenderResult, error) {
|
func (rs *RenderingService) render(ctx context.Context, opts Opts, renderKeyProvider renderKeyProvider) (*RenderResult, error) {
|
||||||
if int(atomic.LoadInt32(&rs.inProgressCount)) > opts.ConcurrentLimit {
|
if int(atomic.LoadInt32(&rs.inProgressCount)) > opts.ConcurrentLimit {
|
||||||
rs.log.Warn("Could not render image, hit the currency limit", "concurrencyLimit", opts.ConcurrentLimit, "path", opts.Path)
|
rs.log.Warn("Could not render image, hit the currency limit", "concurrencyLimit", opts.ConcurrentLimit, "path", opts.Path)
|
||||||
|
if opts.ErrorConcurrentLimitReached {
|
||||||
|
return nil, ErrConcurrentLimitReached
|
||||||
|
}
|
||||||
|
|
||||||
theme := models.ThemeDark
|
theme := models.ThemeDark
|
||||||
if opts.Theme != "" {
|
if opts.Theme != "" {
|
||||||
@ -250,6 +253,9 @@ func (rs *RenderingService) render(ctx context.Context, opts Opts, renderKeyProv
|
|||||||
rs.log.Warn("Could not render image, no image renderer found/installed. " +
|
rs.log.Warn("Could not render image, no image renderer found/installed. " +
|
||||||
"For image rendering support please install the grafana-image-renderer plugin. " +
|
"For image rendering support please install the grafana-image-renderer plugin. " +
|
||||||
"Read more at https://grafana.com/docs/grafana/latest/administration/image_rendering/")
|
"Read more at https://grafana.com/docs/grafana/latest/administration/image_rendering/")
|
||||||
|
if opts.ErrorRenderUnavailable {
|
||||||
|
return nil, ErrRenderUnavailable
|
||||||
|
}
|
||||||
return rs.renderUnavailableImage(), nil
|
return rs.renderUnavailableImage(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -102,6 +103,22 @@ func TestRenderErrorImage(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type unavailableRendererManager struct{}
|
||||||
|
|
||||||
|
func (m unavailableRendererManager) Renderer() *plugins.Plugin { return nil }
|
||||||
|
|
||||||
|
func TestRenderUnavailableError(t *testing.T) {
|
||||||
|
rs := RenderingService{
|
||||||
|
Cfg: &setting.Cfg{},
|
||||||
|
log: log.New("test"),
|
||||||
|
RendererPluginManager: unavailableRendererManager{},
|
||||||
|
}
|
||||||
|
opts := Opts{ErrorOpts: ErrorOpts{ErrorRenderUnavailable: true}}
|
||||||
|
result, err := rs.Render(context.Background(), opts, nil)
|
||||||
|
assert.Equal(t, ErrRenderUnavailable, err)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
}
|
||||||
|
|
||||||
func TestRenderLimitImage(t *testing.T) {
|
func TestRenderLimitImage(t *testing.T) {
|
||||||
path, err := filepath.Abs("../../../")
|
path, err := filepath.Abs("../../../")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -146,6 +163,22 @@ func TestRenderLimitImage(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRenderLimitImageError(t *testing.T) {
|
||||||
|
rs := RenderingService{
|
||||||
|
Cfg: &setting.Cfg{},
|
||||||
|
inProgressCount: 2,
|
||||||
|
log: log.New("test"),
|
||||||
|
}
|
||||||
|
opts := Opts{
|
||||||
|
ErrorOpts: ErrorOpts{ErrorConcurrentLimitReached: true},
|
||||||
|
ConcurrentLimit: 1,
|
||||||
|
Theme: models.ThemeDark,
|
||||||
|
}
|
||||||
|
result, err := rs.Render(context.Background(), opts, nil)
|
||||||
|
assert.Equal(t, ErrConcurrentLimitReached, err)
|
||||||
|
assert.Nil(t, result)
|
||||||
|
}
|
||||||
|
|
||||||
func TestRenderingServiceGetRemotePluginVersion(t *testing.T) {
|
func TestRenderingServiceGetRemotePluginVersion(t *testing.T) {
|
||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
rs := &RenderingService{
|
rs := &RenderingService{
|
||||||
|
Loading…
Reference in New Issue
Block a user