Get error response when query data in data source plugin development

Hi everyone,

I am developing a data source plugin. I stumble upon this requirement of reading additional information in response header of an error response when query data.

As you may know, query method for data source plugin returns an Observable object, which is then managed by Grafana. It seems like for error response, it doesn’t get return to plugin, but get throw as an error right away.

My question is that is it possible to handle error responses 4xx or 5xx by the plugin itself and how to do it?

Thanks in advance.

Hi Vien. Are you developing a frontend or backend datasource plugin?

Hi,
It’s a frontend datasource plugin.

Can you share the code you are using to query your datasource? You should be able to use a try/catch in any method to request data and observe the results.

Below is portion of the code which have been reduced only for question. This is the query method in DataSource.ts.
Edit for additional info: I tried try/catch for the whole fetch method, but the error is still not managed in this try/catch.

// Code is reduced of unnecessaries

query(options: DataQueryRequest<MyQuery>): Observable < DataQueryResponse > {
  const streams: Array<Observable< DataQueryResponse >> =[];

  const stream = this.fetchData({
    method: 'POST',
    url: this.getRootURL(),
    headers: this.headers,
    data: { },
  }, (response: FetchResponse) => {
    // Handling reponse.
    // Error response does not come in here.
  });


  streams.push(stream);

  return merge(...streams);
}

fetchData(options: BackendSrvRequest, process: Function): Observable < any > {
  return getBackendSrv()
    .fetch(options)
    .pipe(
      map((response: FetchResponse) => {
        return process(response);
      })
    );
}

If you don’t need to use the observable directly you can instead use lastValueFrom from rxjs that returns a promise. then you can try/catch the await for it. You can follow an example here grafana-plugin-examples/DataSource.ts at main · grafana/grafana-plugin-examples · GitHub

your code somewhat could be like this

// notice this now returns a promise instead of accepting a callback
// you can try/catch when calling this.fetchData
 async fetchData(url: string, params?: string) {
    const response = getBackendSrv().fetch<DataSourceResponse>({
      url: `${this.baseUrl}${url}${params?.length ? `?${params}` : ''}`,
    });
    return lastValueFrom(response);
  }

If you need to use the observable object iself you can see the rxjs documentation to catch errors catch / catchError - Learn RxJS

Keep in mind these observables are not managed by Grafana. They are all come from the library rxjs so it is best to consult their documentation.

1 Like

Thank you for your quick and detailed response. I find that catchError is the answer to my problem.

Edit: Sorry. I was too quick in responding. This does give an idea to handle error, however what I actually need is the response headers of the request. With catchError, I can access to the body of response but not the headers.
Do you have an idea?

hi @vien if you don’t see it available then it is unlikely you can have access to the response in a frontend plugin. In such case then a backend plugin should be more suitable for your case.

1 Like

Thank you @academo . I will look into it. Thanks for your time and help. It does give me lots of insight.