Skip to main content

Error Handling

Errors in Vendure can be divided into two categories:

  • Unexpected errors
  • Expected errors

These two types have different meanings and are handled differently from one another.

Unexpected Errors

This type of error occurs when something goes unexpectedly wrong during the processing of a request. Examples include internal server errors, database connectivity issues, lacking permissions for a resource, etc. In short, these are errors that are not supposed to happen.

Internally, these situations are handled by throwing an Error:

Ts

In the GraphQL APIs, these errors are returned in the standard errors array:

Json

So your client applications need a generic way of detecting and handling this kind of error. For example, many http client libraries support "response interceptors" which can be used to intercept all API responses and check the errors array.

Note

GraphQL will return a 200 status even if there are errors in the errors array. This is because in GraphQL it is still possible to return good data alongside any errors.

Here's how it might look in a simple Fetch-based client:

src/client.ts

Expected errors (ErrorResults)

This type of error represents a well-defined result of (typically) a GraphQL mutation which is not considered "successful". For example, when using the applyCouponCode mutation, the code may be invalid, or it may have expired. These are examples of "expected" errors and are named in Vendure "ErrorResults". These ErrorResults are encoded into the GraphQL schema itself.

ErrorResults all implement the ErrorResult interface:

Graphql

Some ErrorResults add other relevant fields to the type:

Graphql

Operations that may return ErrorResults use a GraphQL union as their return type:

Graphql

Querying an ErrorResult union

When performing an operation of a query or mutation which returns a union, you will need to use the GraphQL conditional fragment to select the desired fields:

Graphql
Note

The __typename field is added by GraphQL to all object types, so we can include it no matter whether the result will end up being an Order object or an ErrorResult object. We can then use the __typename value to determine what kind of object we have received.

Some clients such as Apollo Client will automatically add the __typename field to all queries and mutations. If you are using a client which does not do this, you will need to add it manually.

Here's how a response would look in both the success and error result cases:

Json

Handling ErrorResults in plugin code

If you are writing a plugin which deals with internal Vendure service methods that may return ErrorResults, then you can use the isGraphQlErrorResult() function to check whether the result is an ErrorResult:

Ts

Handling ErrorResults in client code

Because we know all possible ErrorResult that may occur for a given mutation, we can handle them in an exhaustive manner. In other words, we can ensure our storefront has some sensible response to all possible errors. Typically this will be done with a switch statement:

Ts

If we combine this approach with GraphQL code generation, then TypeScript will even be able to help us ensure that we have handled all possible ErrorResults:

Ts

Live example

Here is a live example which the handling of unexpected errors as well as ErrorResults:

Was this chapter helpful?
Report Issue
Edited Feb 10, 2026ยทEdit this page