Plugins: Capture error source from grpc status errors (#97471)

* capture errorsource from grpc error

* apply PR feedback

* update comment

* update comment

* use SDK logic

* update SDK commit

* update sdk

* update golden files
This commit is contained in:
Will Browne
2025-01-08 17:05:28 +00:00
committed by GitHub
parent 8cb7159872
commit 5a2315dabf
24 changed files with 464 additions and 348 deletions

View File

@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/grpcplugin"
errstatus "github.com/grafana/grafana-plugin-sdk-go/experimental/status"
"github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2"
"github.com/hashicorp/go-plugin"
"google.golang.org/grpc/codes"
@ -19,6 +20,10 @@ import (
"github.com/grafana/grafana/pkg/plugins/log"
)
var (
logger = log.New("plugins.clientv2")
)
type ClientV2 struct {
grpcplugin.DiagnosticsClient
grpcplugin.ResourceClient
@ -186,6 +191,9 @@ func (c *ClientV2) QueryData(ctx context.Context, req *backend.QueryDataRequest)
return nil, plugins.ErrMethodNotImplemented
}
if errorSource, ok := backend.ErrorSourceFromGrpcStatusError(ctx, err); ok {
return nil, handleGrpcStatusError(ctx, errorSource, err)
}
return nil, fmt.Errorf("%v: %w", "Failed to query data", err)
}
@ -338,3 +346,25 @@ func (c *ClientV2) ConvertObjects(ctx context.Context, req *backend.ConversionRe
return backend.FromProto().ConversionResponse(protoResp), nil
}
// handleGrpcStatusError sets the error source via context based on the error source provided. Regardless of its value,
// a plugin downstream error is returned as both plugin and downstream errors are treated the same in Grafana.
func handleGrpcStatusError(ctx context.Context, errorSource errstatus.Source, err error) error {
switch errorSource {
case backend.ErrorSourceDownstream:
innerErr := backend.WithErrorSource(ctx, backend.ErrorSourceDownstream)
if innerErr != nil {
logger.Error("Could not set downstream error source", "error", innerErr)
}
return plugins.ErrPluginDownstreamErrorBase.Errorf("%v", err)
case backend.ErrorSourcePlugin:
errorSourceErr := backend.WithErrorSource(ctx, backend.ErrorSourcePlugin)
if errorSourceErr != nil {
logger.Error("Could not set plugin error source", "error", errorSourceErr)
}
// a downstream error is returned here as plugin errors are considered as downstream errors in the
// context of the Grafana server.
return plugins.ErrPluginDownstreamErrorBase.Errorf("%v", err)
}
return fmt.Errorf("%v: %w", "Failed to query data", err)
}