From fcb1e9c9e55112306d65400da462339611cbd3d2 Mon Sep 17 00:00:00 2001 From: Sriram <153843+yesoreyeram@users.noreply.github.com> Date: Fri, 16 May 2025 11:51:12 +0100 Subject: [PATCH] Postgres: Improve invalid port specifier error during health check (#105536) normalize error message in postgres invalid port specifier error --- pkg/tsdb/grafana-postgresql-datasource/postgres.go | 6 +++--- .../grafana-postgresql-datasource/sqleng/errors.go | 7 +++++++ .../sqleng/handler_checkhealth.go | 6 ++++++ .../sqleng/handler_checkhealth_test.go | 10 ++++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 pkg/tsdb/grafana-postgresql-datasource/sqleng/errors.go diff --git a/pkg/tsdb/grafana-postgresql-datasource/postgres.go b/pkg/tsdb/grafana-postgresql-datasource/postgres.go index 66362d302e1..7b7422f3094 100644 --- a/pkg/tsdb/grafana-postgresql-datasource/postgres.go +++ b/pkg/tsdb/grafana-postgresql-datasource/postgres.go @@ -187,7 +187,7 @@ func (s *Service) generateConnectionString(dsInfo sqleng.DataSourceInfo) (string var err error port, err = strconv.Atoi(sp[1]) if err != nil { - return "", fmt.Errorf("invalid port in host specifier %q: %w", sp[1], err) + return "", fmt.Errorf("%w %q: %w", sqleng.ErrInvalidPortSpecified, sp[1], err) } logger.Debug("Generating connection string with network host/port pair", "host", host, "port", port) @@ -200,7 +200,7 @@ func (s *Service) generateConnectionString(dsInfo sqleng.DataSourceInfo) (string var err error port, err = strconv.Atoi(dsInfo.URL[index+1:]) if err != nil { - return "", fmt.Errorf("invalid port in host specifier %q: %w", dsInfo.URL[index+1:], err) + return "", fmt.Errorf("%w %q: %w", sqleng.ErrInvalidPortSpecified, dsInfo.URL[index+1:], err) } logger.Debug("Generating ipv6 connection string with network host/port pair", "host", host, "port", port) @@ -260,7 +260,7 @@ func (t *postgresQueryResultTransformer) TransformQueryError(_ log.Logger, err e func (s *Service) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) { dsHandler, err := s.getDSInfo(ctx, req.PluginContext) if err != nil { - return &backend.CheckHealthResult{Status: backend.HealthStatusError, Message: err.Error()}, nil + return sqleng.ErrToHealthCheckResult(err) } return dsHandler.CheckHealth(ctx, req) } diff --git a/pkg/tsdb/grafana-postgresql-datasource/sqleng/errors.go b/pkg/tsdb/grafana-postgresql-datasource/sqleng/errors.go new file mode 100644 index 00000000000..e519ee87fe2 --- /dev/null +++ b/pkg/tsdb/grafana-postgresql-datasource/sqleng/errors.go @@ -0,0 +1,7 @@ +package sqleng + +import "errors" + +var ( + ErrInvalidPortSpecified error = errors.New("invalid port in host specifier") +) diff --git a/pkg/tsdb/grafana-postgresql-datasource/sqleng/handler_checkhealth.go b/pkg/tsdb/grafana-postgresql-datasource/sqleng/handler_checkhealth.go index abe98fff713..f05d75791ad 100644 --- a/pkg/tsdb/grafana-postgresql-datasource/sqleng/handler_checkhealth.go +++ b/pkg/tsdb/grafana-postgresql-datasource/sqleng/handler_checkhealth.go @@ -81,6 +81,12 @@ func ErrToHealthCheckResult(err error) (*backend.CheckHealthResult, error) { details["verboseMessage"] = pqErr.Message } } + if errors.Is(err, ErrInvalidPortSpecified) { + res.Message = fmt.Sprintf("Connection string error: %s", ErrInvalidPortSpecified.Error()) + if unwrappedErr := errors.Unwrap(err); unwrappedErr != nil { + details["verboseMessage"] = unwrappedErr.Error() + } + } detailBytes, marshalErr := json.Marshal(details) if marshalErr != nil { return res, nil diff --git a/pkg/tsdb/grafana-postgresql-datasource/sqleng/handler_checkhealth_test.go b/pkg/tsdb/grafana-postgresql-datasource/sqleng/handler_checkhealth_test.go index b3f8736407d..f7b010dd0f2 100644 --- a/pkg/tsdb/grafana-postgresql-datasource/sqleng/handler_checkhealth_test.go +++ b/pkg/tsdb/grafana-postgresql-datasource/sqleng/handler_checkhealth_test.go @@ -2,6 +2,7 @@ package sqleng import ( "errors" + "fmt" "net" "testing" @@ -48,6 +49,15 @@ func TestErrToHealthCheckResult(t *testing.T) { JSONDetails: []byte(`{"errorDetailsLink":"https://grafana.com/docs/grafana/latest/datasources/postgres","verboseMessage":"internal server error"}`), }, }, + { + name: "invalid port specifier error", + err: fmt.Errorf("%w %q: %w", ErrInvalidPortSpecified, `"foo.bar.co"`, errors.New(`strconv.Atoi: parsing "foo.bar.co": invalid syntax`)), + want: &backend.CheckHealthResult{ + Status: backend.HealthStatusError, + Message: "Connection string error: invalid port in host specifier", + JSONDetails: []byte(`{"errorDetailsLink":"https://grafana.com/docs/grafana/latest/datasources/postgres","verboseMessage":"invalid port in host specifier \"\\\"foo.bar.co\\\"\": strconv.Atoi: parsing \"foo.bar.co\": invalid syntax"}`), + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {