Pass through error from REST upstream service with UDG

Hi guys , I am trying the tyk pro demo , and here’s my configuration:

I use UDG as graphql gateway that hits REST upstream services. But when there are error returned from the REST service (e.g. 400 Bad Request / 500 Internal Server Error) ; the graphql only returns null on the data.

My question for the purpose of error validation on the client side is:

  1. Can we pass through these errors and return errors object at the graphql schema ?
    If yes, can we customize the errors schema returned?
  2. Can we change the http status code so that if the upstream service return 400 Bad Request, the graphql doesn’t return 200 OK?

@agata-wit Any thoughts?

Hi @midnight,
welcome to the Community!

At this point the short answer would be “no”. But nobody likes a short one, especially if it’s not positive, so I’ll try to elaborate a bit on where we are currently and what’s happening in terms of our roadmap for - what I will generally call - “UDG datasources error handling”.

You seem to be running a very simple use case - one REST API “wrapped” in GQL using UDG. That single REST datasource sometimes returns errors and what your UDG consumer is seeing is 200 OK http response with an empty data object in the response body.
It looks easy on the surface - just override the 200 OK code with whatever 4xx or 5xx is returned by the upstream and pass the error message in error object.

But because UDG is capable of fetching data from multiple datasources, there’s usually a more complex use case our users are or will be facing. Say only 2 out of 5 UDG datasources return errors, the rest of the data comes back without issues and can be parsed and returned in the query response. Should the 200 OK still be overridden by one of the 2 error codes? If so, which one in case they are different - like 401 and 500? Should we still return the partial response that the other 3 working datasources provided?

I could go on, because those are exactly the questions we are currently asking ourselves when discussing and designing the error handling in UDG.
If, while looking at UDG for your use case, you have any expectations that you would like to share with us, I will appreciate it greatly, it will definitely help us design this feature better.

One idea that I have as a possible workaround would be to extend your UDG schema something like this:

type Query {
    myQuery: Information
}

type Information {
    id: ID!
    foo: String
    fee: String
    errors: [Error]
}

type Error {
    code: Int
    message: String
}

Of course type Error would need to reflect your REST error response schema, I used code/message as an example.
But if you do it this way it will mean that consumers would need to include field errors from type Information with every query they send. When the REST datasource returns no error, that field will come back with null, but when it does, then all the other requested fields would be null and errors would have a value.

I’ll be honest, I did not try it myself yet, but I will and let you know how it worked.

1 Like

Hi @agata-wit ,
Thanks for your response !

A little update from me, actually I was searching for the way to override the http code, and i was able to change the http response code via Response Plugin.

My use case, which fetches data from multiple data sources is similar to your example workaround. I want to fetches data from multiple datasources and return all errors that occurs from all the endpoint. But looking at your example, I think it just fetches from one datasource. My next question is if I have a supergraph that fetches from another REST endpoint and also return same Error object, how can we aggregate those errors into one object in the UDG?

e.g.:

type Query {
    myQuery: Information
}

type Information {
    id: ID!
    foo: String
    fee: Fee
    errors: [Error]
}

type Error {
    code: Int
    message: String
}


type Fee{
    data: String
    error: Error
}

where Fee is another object from different REST endpoint

So I can do this query

myQuery {
   foo
   fee {
      data
      error
   }
   errors
}

but i want the response to be something like

{
"foo" :"xxxxxx",

"fee": {
   "data": "Fee Data",
    "error" : {"code":400 ,"message":"Fee Error"}
}
"errors": [ 
     {"code":500 ,"message" : "info error" },
     {"code":400 ,"message":"Fee Error"}
  ]
}

So i want to return all the errors at the information objects error. What do you think if i want to do this?

Another problem is , if i return 400 http error code from the upstream REST service, I can I get the data at the udg? or it will automatically resolve to nil?