6. Resolving a mutation with errors
2m

🚨 Handling the error case

As we saw in the REST API, it's possible to get a 404 Not Found response when trying to update a track that doesn't exist. Let's look at how to return the appropriate when that happens.

Let's open up the resolvers.js file again in the server/src folder.

We've got our successful response for our incrementTrackViews ready. To handle the situation where the TrackAPI call throws an error, let's wrap this section in a try block.

When the error is thrown, we'll make sure to catch it by adding a catch, which takes the error as a parameter.

incrementTrackViews: async (_, {id}, {dataSources}) => {
try {
const track = await dataSources.trackAPI.incrementTrackViews(id);
return {
code: 200,
success: true,
message: `Successfully incremented number of views for track ${id}`,
track
};
} catch (err) {
return {
// we'll return a new object here
};
}
},

Then, we return an object with the same properties as the object in the success case, but with different values.

We could set the code to be 404, but we can also be more dynamic and use the values that and the RESTDataSource class provide. When an error occurs, attaches an extensions to that error that contains relevant error details.

In this case, as our TrackAPI extends RESTDataSource, this extensions object will be enriched with a response property, which provides some additional information about the HTTP response itself. We can return the status property, which refers to the HTTP status code. Perfect to use here!

code: err.extensions.response.status,

Next, we can set our success property to false.

success: false,

For the message property, we can craft a custom one, but let's use another value from the same extensions.response object. That's the extensions.response.body property. It makes this value more dynamic, since it might return other types of errors in the future.

message: err.extensions.response.body,

Finally, we'll add a track property and set it to null, because the object was not successfully modified.

Which of the following statements are true about the err.extensions fields returned by the server?

The incrementTrackViews should now look like this, with the error handling added in:

incrementTrackViews: async (_, {id}, {dataSources}) => {
try {
const track = await dataSources.trackAPI.incrementTrackViews(id);
return {
code: 200,
success: true,
message: `Successfully incremented number of views for track ${id}`,
track
};
} catch (err) {
return {
code: err.extensions.response.status,
success: false,
message: err.extensions.response.body,
track: null
};
}
},
The resolver handles both a successful response and possible errors. Which of these are true about the return objects for those two cases?
Code Challenge!

We start with the same assignSpaceship Mutation resolver example as in the previous code challenge. This time, we assume the dataSources.spaceAPI.assignSpaceshipToMission() call will return an error. Modify the following piece of code to properly handle the error returned by the API and return a properly formatted object that conforms to the schema definition of the AssignSpaceshipResponse type. Remember to use a try/catch block and to return dynamic error data when possible.

Awesome, this is ready to go and ready to be tested in the Explorer! Let's get to it.

Previous

Share your questions and comments about this lesson

Your feedback helps us improve! If you're stuck or confused, let us know and we'll help you out. All comments are public and must follow the Apollo Code of Conduct. Note that comments that have been resolved or addressed may be removed.

You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.