Skip to content

fix: return CallResource errors as HTTP responses instead of Go errors - #663

Open
nhuisman-amz wants to merge 1 commit into
grafana:mainfrom
nhuisman-amz:fix/callresource-error-handling
Open

fix: return CallResource errors as HTTP responses instead of Go errors#663
nhuisman-amz wants to merge 1 commit into
grafana:mainfrom
nhuisman-amz:fix/callresource-error-handling

Conversation

@nhuisman-amz

Copy link
Copy Markdown

Summary

Replace return err with sendError(sender, err) in all CallResource error paths so that downstream errors (e.g. IAM AccessDeniedException) are returned to the user as HTTP responses instead of being sanitized to a generic plugin.downstreamError.

Fixes #662

Problem

When CallResource endpoints (/databases, /tables, /measures, /dimensions) encounter errors from the Timestream API, they return the error as a Go error. Grafana server treats this as an unhandled plugin failure and returns a generic HTTP 500 with plugin.downstreamError, discarding the actual error message.

Users see:

An error occurred within the plugin

Instead of the actionable error:

AccessDeniedException: User: arn:aws:sts::123456789012:assumed-role/MyRole/session
is not authorized to perform: timestream:ListMeasures ...

Fix

Added a sendError() helper that sends errors as HTTP responses via sender.Send(), and replaced all 5 return err paths in CallResource:

func sendError(sender backend.CallResourceResponseSender, err error) error {
    return sender.Send(&backend.CallResourceResponse{
        Status: http.StatusInternalServerError,
        Body:   []byte(err.Error()),
    })
}

This matches how CheckHealth already surfaces errors — by returning them as structured responses rather than Go errors.

Affected endpoints

  • /databases — query error (1 path)
  • /tables — unmarshal error, query error (2 paths)
  • /measures — unmarshal error, query error (2 paths)
  • /dimensions — shares the measures/dimensions block above

Testing

  • go build ./pkg/timestream/ passes
  • Verified locally with a Timestream datasource using a role missing timestream:ListMeasures — the measures dropdown now shows the AccessDeniedException message instead of the generic error

@nhuisman-amz
nhuisman-amz requested a review from a team as a code owner April 18, 2026 01:06
@cla-assistant

cla-assistant Bot commented Apr 18, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@itsgareth itsgareth left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dgiagio dgiagio left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checks are failing

@alyssajoyner

Copy link
Copy Markdown

@nhuisman-amz and @itsgareth - please ensure your commits are signed so we can merge this PR in 😊

@itsgareth

Copy link
Copy Markdown
Member

hey, @nhuisman-amz sorry for the long wait time on this pr being merged, one final thing, can you please make sure all commits in this pr are signed, this is a blocking requirement before any pr can be merged.

@nhuisman-amz
nhuisman-amz force-pushed the fix/callresource-error-handling branch from 7bd428c to f783fc1 Compare August 7, 2026 05:48
@nhuisman-amz

Copy link
Copy Markdown
Author

hey, @nhuisman-amz sorry for the long wait time on this pr being merged, one final thing, can you please make sure all commits in this pr are signed, this is a blocking requirement before any pr can be merged.

signed commits

…urning Go errors

When CallResource endpoints (/databases, /tables, /measures, /dimensions)
encounter errors, they returned Go errors directly. Grafana server treats
returned errors as unhandled plugin failures and sanitizes them to a
generic "plugin.downstreamError" HTTP 500, hiding actionable messages
like AccessDeniedException from users.

Add sendError() helper that sends errors as HTTP responses via
sender.Send(), ensuring error messages reach the browser. This matches
how CheckHealth already surfaces errors to users.
@njvrzm
njvrzm force-pushed the fix/callresource-error-handling branch from f783fc1 to 28ff991 Compare August 18, 2026 08:21
@github-actions

Copy link
Copy Markdown

Signed commits report

1 of 1 commit between main and fix/callresource-error-handling could not be fully verified:

Commit Author Reason Message
28ff991f nhuisman-amz unsigned fix: return error responses via sender in CallResource instead of returning Go errors

This repository requires all commits to be signed. See GitHub docs on commit signature verification.

@njvrzm

njvrzm commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

@nhuisman-amz - my apologies, I rebased this since it had been a while and that's unverified the commit signatures, if you could please sign again I'll follow up and get this merged ASAP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CallResource error paths return Go errors instead of HTTP responses, hiding actionable error messages from users

8 participants