Error Management
Managing errors is an essential part of the integration with any API. Although we strive to provide a perfectly stable service, it's reasonable to expect technical errors occasionally. In this section we'll list the various error cases you may encounter, and what they mean.
When using our GraphQL API (or any other GraphQL API over HTTP) there are two levels of error to consider: request errors and field errors. But first let's have a look at how a standard GraphQL error is formatted.
Error format
GraphQL errors are standardised, and you can expect our GraphQL API to follow the format of the official GraphQL specification. In practice here's an example of error you might encounter:
Please note that you might find an attribute named code
under the extensions
object. This attribute is deprecated and should not be used under any circumstances. If you're looking for a stable error identifier, use the name
attribute. You can see the most frequent ones below.
Request errors
A request error occurs when a whole request has been dismissed as being impossible to execute. Causes may vary and could be as wide as an invalid request, to our service being temporarily unavailable. Here are the possible request errors:
400
The request was invalid. This could be because there was: - A syntax error in the request, such as a missing quote or brace. - A schema error in the request, such as a typo in a field name.
401
415
The content type provided in the HTTP request is invalid. In practice this means you're probably missing the content-type: application/json
header.
429
500
There was an unexpected technical error during the execution of the request.
502
The GraphQL server is currently unable to process any request.
504
The GraphQL server failed to respond in time to the request.
Field errors
A field error occurs when a request was valid but a technical error happened while trying to resolve one of the fields. Causes may vary but the errors will always be listed as part of the response payload. This is described in the official GraphQL specification, and is a behaviour that contrasts with a typical REST API. Indeed, it becomes possible to have a response containing partial data and an error list while returning an HTTP 200 status code.
As a user of a GraphQL API you must therefore always check the errors
array in the response to ensure no error would prevent you from accessing the data you need.
Here's an example of such an error:
As you can see in the error above, our errors contain the extensions
object. As per the GraphQL specs, this object is here to add any data that would be relevant to the error. Our API will always contain a unique identifier under the name
attribute. This attribute will inform you of the type of error that was encountered. These type of errors are specific to the query or mutation being executed, and will generally be documented on the query or mutation directly, though here's a list of the standard error type you might encounter:
INTERNAL_ERROR
Our GraphQL encountered a technical error. This error might be temporary (such as hardware failure, network error, etc.) or might be due to a bug that requires fixing on our end.
INVALID_ARGUMENT
One of the arguments of the query or mutation you provided wasn't valid. This could be a type error, parsing error, or another validation. See the message
attribute for details.
NOT_FOUND
The resource wasn't found.
PERMISSION_DENIED
The request was successfully authorized, but the permissions of the user aren't sufficient to execute the request.
UNAUTHORIZED
The request failed to be authorized. This is likely caused by an invalid authorization token, such as an expired token.
Retry Policy
When the whole query has failed, or when a partial result is not acceptable for the consumer, it is sometimes possible to retry the request shortly after encountering an error. Not all errors are retriable, for instance an INVALID_ARGUMENT will still be invalid even after retrying.
To simplify the logic implemented on the consumer side, we've set an attribute named retryPolicy
which informs the consumer if a retry is possible, and what to do. Bear in mind that when implementing a retry policy, avoiding infinite loops is extremely important. When implementing a retry, please add this header to your HTTP request: x-iAdvize-retry-count
that contains the number of attempts for a given request.
Here are the possible values for the retryPolicy
attribute, and what to do with it:
null
or undefined
Same as NO_RETRY
NO_RETRY
No retry should be immediately attempted. This category of error is usually due to a consumer implementation error, such as a permission error or an invalid argument.
RETRY_ONCE
Your program can immediately retry the request. This retry policy is attached to errors that are transient, such as networking failure or hardware failure. Retrying may succeed. When implementing the single retry, be mindful to avoid infinite loops.
EXPONENTIAL_BACKOFF
Rate limit
To ensure a good quality of service, we limit how many requests a single client can send to our system. This limit is set above 50 requests per second.
If you were faced with HTTP return codes 429, this would means you've exceeded that rate and you should reduce the rate at which requests are being sent to our systems. You could also implement the EXPONENTIAL_BACKOFF
as described in the retry policy section.
Other general good practices
When dealing with errors there are some industry standard practices to put in place, such as logging to help diagnose any issue. A good error log would contain:
A timestamp with a timezone
The URL that was hit
The HTTP request, containing the HTTP verb, the body (such as json), and the headers
The HTTP response, containing the HTTP status code, the headers and the body
These are crucial pieces of information allowing anyone to then investigate a potential issue.
Other, more advanced, practices such as gathering metrics about response time an error rates might also be useful.
Last updated