From 0f4a47b18095fe0651947fde24cbb20f5141c880 Mon Sep 17 00:00:00 2001 From: Andres Martinez Gotor <andres.martinez@grafana.com> Date: Thu, 18 Apr 2024 13:04:22 +0200 Subject: [PATCH] Plugin load errors: Add more well-known errors (#85960) --- packages/grafana-data/src/types/plugin.ts | 2 ++ .../manager/pipeline/initialization/steps.go | 7 ++++-- .../manager/pipeline/validation/steps.go | 5 ++++- pkg/plugins/models.go | 22 ++++++++++++++++--- .../pluginsintegration/pipeline/steps.go | 1 + .../components/PluginDetailsDisabledError.tsx | 5 +++++ 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/packages/grafana-data/src/types/plugin.ts b/packages/grafana-data/src/types/plugin.ts index 5c934d3b299..c006b72fe45 100644 --- a/packages/grafana-data/src/types/plugin.ts +++ b/packages/grafana-data/src/types/plugin.ts @@ -43,6 +43,8 @@ export enum PluginErrorCode { missingSignature = 'signatureMissing', invalidSignature = 'signatureInvalid', modifiedSignature = 'signatureModified', + failedBackendStart = 'failedBackendStart', + angular = 'angular', } /** Describes error returned from Grafana plugins API call */ diff --git a/pkg/plugins/manager/pipeline/initialization/steps.go b/pkg/plugins/manager/pipeline/initialization/steps.go index c27cf667602..2df09d1144a 100644 --- a/pkg/plugins/manager/pipeline/initialization/steps.go +++ b/pkg/plugins/manager/pipeline/initialization/steps.go @@ -79,8 +79,11 @@ func newBackendProcessStarter(processManager process.Manager) *BackendClientStar // Start will start the backend plugin process. func (b *BackendClientStarter) Start(ctx context.Context, p *plugins.Plugin) (*plugins.Plugin, error) { if err := b.processManager.Start(ctx, p); err != nil { - b.log.Error("Could not start plugin", "pluginId", p.ID, "error", err) - return nil, err + b.log.Error("Could not start plugin backend", "pluginId", p.ID, "error", err) + return nil, (&plugins.Error{ + PluginID: p.ID, + ErrorCode: plugins.ErrorCodeFailedBackendStart, + }).WithMessage(err.Error()) } return p, nil } diff --git a/pkg/plugins/manager/pipeline/validation/steps.go b/pkg/plugins/manager/pipeline/validation/steps.go index 20dee23f780..10af0cce5e4 100644 --- a/pkg/plugins/manager/pipeline/validation/steps.go +++ b/pkg/plugins/manager/pipeline/validation/steps.go @@ -106,7 +106,10 @@ func (a *AngularDetector) Validate(ctx context.Context, p *plugins.Plugin) error // Do not initialize plugins if they're using Angular and Angular support is disabled if p.Angular.Detected && !a.cfg.AngularSupportEnabled { a.log.Error("Refusing to initialize plugin because it's using Angular, which has been disabled", "pluginId", p.ID) - return errors.New("angular plugins are not supported") + return (&plugins.Error{ + PluginID: p.ID, + ErrorCode: plugins.ErrorAngular, + }).WithMessage("angular plugins are not supported") } } p.Angular.HideDeprecation = slices.Contains(a.cfg.HideAngularDeprecation, p.ID) diff --git a/pkg/plugins/models.go b/pkg/plugins/models.go index f9e263eefe4..0b76206fe08 100644 --- a/pkg/plugins/models.go +++ b/pkg/plugins/models.go @@ -235,9 +235,11 @@ type AppDTO struct { } const ( - errorCodeSignatureMissing ErrorCode = "signatureMissing" - errorCodeSignatureModified ErrorCode = "signatureModified" - errorCodeSignatureInvalid ErrorCode = "signatureInvalid" + errorCodeSignatureMissing ErrorCode = "signatureMissing" + errorCodeSignatureModified ErrorCode = "signatureModified" + errorCodeSignatureInvalid ErrorCode = "signatureInvalid" + ErrorCodeFailedBackendStart ErrorCode = "failedBackendStart" + ErrorAngular ErrorCode = "angular" ) type ErrorCode string @@ -246,9 +248,14 @@ type Error struct { ErrorCode `json:"errorCode"` PluginID string `json:"pluginId,omitempty"` SignatureStatus SignatureStatus `json:"status,omitempty"` + message string `json:"-"` } func (e Error) Error() string { + if e.message != "" { + return e.message + } + if e.SignatureStatus != "" { switch e.SignatureStatus { case SignatureStatusInvalid: @@ -266,6 +273,10 @@ func (e Error) Error() string { } func (e Error) AsErrorCode() ErrorCode { + if e.ErrorCode != "" { + return e.ErrorCode + } + switch e.SignatureStatus { case SignatureStatusInvalid: return errorCodeSignatureInvalid @@ -280,6 +291,11 @@ func (e Error) AsErrorCode() ErrorCode { return "" } +func (e *Error) WithMessage(m string) *Error { + e.message = m + return e +} + // Access-Control related definitions // RoleRegistration stores a role and its assignments to basic roles diff --git a/pkg/services/pluginsintegration/pipeline/steps.go b/pkg/services/pluginsintegration/pipeline/steps.go index 85adcc6c60d..5401323d41b 100644 --- a/pkg/services/pluginsintegration/pipeline/steps.go +++ b/pkg/services/pluginsintegration/pipeline/steps.go @@ -89,6 +89,7 @@ func newRegisterPluginRoles(registry plugins.RoleRegistry) *RegisterPluginRoles func (r *RegisterPluginRoles) Register(ctx context.Context, p *plugins.Plugin) (*plugins.Plugin, error) { if err := r.roleRegistry.DeclarePluginRoles(ctx, p.ID, p.Name, p.Roles); err != nil { r.log.Warn("Declare plugin roles failed.", "pluginId", p.ID, "error", err) + return nil, err } return p, nil } diff --git a/public/app/features/plugins/admin/components/PluginDetailsDisabledError.tsx b/public/app/features/plugins/admin/components/PluginDetailsDisabledError.tsx index 344e287f283..d7ca8094e17 100644 --- a/public/app/features/plugins/admin/components/PluginDetailsDisabledError.tsx +++ b/public/app/features/plugins/admin/components/PluginDetailsDisabledError.tsx @@ -66,6 +66,11 @@ function renderDescriptionFromError(error?: PluginErrorCode): ReactElement { version of this plugin. </p> ); + case PluginErrorCode.failedBackendStart: + return <p>This plugin failed to start. Server logs can provide more information.</p>; + case PluginErrorCode.angular: + // Error message already rendered by AngularDeprecationPluginNotice + return <></>; default: return ( <p>