Handling Errors in Ember Data

Last reviewed on January 18, 2020

In my last post Which Ember Data Serializer Should I Use?, I wrote about the different serializers in Ember Data and their expected API responses. Now let's look at the expected error responses and how to work with errors.

As of Ember Data 2.x, all error responses follow the JSON:API spec. A JSON:API error response looks like this:

{
  "errors": [
    {
      "id": "{unique identifier for this particular occurrence}",
      "links": {
        "about": "{link that leads to further details about this problem}"
      },
      "status": "{HTTP status code}",
      "code": "{application-specific error code}",
      "title": "{summary of the problem}",
      "detail": "{explanation specific to this occurrence of the problem}",
      "source": {
        "pointer": "{a JSON Pointer to the associated entity in the request document}",
        "parameter": "{a string indicating which URI query parameter caused the error}"
      },
      "meta": {}
    }
  ]
}

The response must contain a root key errors which is an array of error objects. Each error object can have any of the properties listed above. To find out more about each property of an error object, visit the JSON:API error documentation.

One thing I want to point out is that the JSON:API spec states that an error object MAY have those members, but which of those properties does Ember Data use?

Let's say we want to create or update a new user record and handle the scenario when there is an error validating the name attribute. What should that error object look like? The two error object properties we will need the API to include are detail and source. For example:

{
  "errors": [
    {
      "detail": "Name is not long enough",
      "source": {
        "pointer": "data/attributes/name"
      }
    }
  ]
}

The property source.pointer is a JSON pointer to a specific attribute, the name attribute in this case. A JSON pointer is a string using a slash-based syntax that identifies a specific value in a JSON document. If we were to look at a user resource following JSON:API, it would look like this:

{
  "data": {
    "type": "users",
    "id": "8",
    "attributes": {
      "name": "David Tang"
    }
  }
}

We can see how the JSON pointer data/attributes/name maps to name in this JSON document. Learn more about JSON pointers here.

Not only does the API need to send the error response formatted as above, but it also needs to send a 422 HTTP status code (Unprocessable Entity). Behind the scenes, when the adapter sees a 422 status code, it rejects the promise with an instance of InvalidError to signal that the record failed server-side validation.

Once we've got that, an errors property will be available on our model.

try {
  await user.save();
} catch (adapterError) {
  console.log(user.errors); // instance of Errors
  console.log(user.errors.name); // array of error objects for the name attribute
  console.log(user.errors.toArray());
  console.log(user.isValid); // false
  console.log(adapterError); // instance of AdapterError
}

As we can see in the catch block, there is a lot of information at our disposal. To display the errors, we can do the following in our template:

{{#each @model.errors.name as |error|}}
  <div class="error">
    {{error.message}}
  </div>
{{/each}}

Accessing the attribute name off of the errors object will return an array of all errors for that attribute.


Pro Ember Data cover
Pro Ember Data available now!

Are you struggling with Ember Data?

In my new book Pro Ember Data, you will learn how to work with Ember Data efficiently, from APIs, adapters, and serializers to polymorphic relationships, using your existing JavaScript and Ember knowledge. This book will teach you how to adapt Ember Data to fit your custom API.

What You'll Learn

  • Review the differences between normalization and serialization
  • Understand how the built-in adapters and serializers in Ember Data
  • Understand how the built-in adapters and serializers in Ember Data work
  • Customize adapters and serializers to consume any API and write them from scratch
  • Handle API errors in Ember Data
  • Work with the Reddit API using Ember Data
  • Learn how to use polymorphic relationships
Check out Pro Ember Data on Amazon using my affiliate link
You can also find Pro Ember Data on Apress.

I've been enjoying @iamdtang's Pro Ember Data book. It's to the point and has lots of great examples. My favorite part was about error handling. This book is perfect after you've exhausted the official guides.

Ilya Radchenko

Product Developer at Applied Geographics

Ilya Radchenko

Pro Ember Data is such an approachable book @iamdtang! Good job. Loving the book so far! Thank you!

Lenora Porter

Software Engineer at Heroku

Lenora Porter

Great to see all those topics in which I struggled when I started working on Ember. Nice job, will check it out :)

AbulAsar S

Fullstack Developer

AbulAsar S

I haven't read David's new book, but his previous Ember Data book helped me a lot when I was starting out with Ember, so I am sure this book is a must if you're working with Ember Data!

Kenneth Larsen

Ember Learning Core Team member

Kenneth Larsen

I bought Ember Data in the Wild back in 2016 and found it really helpful. Looking forward to reading this.

@EmberLinks

Ember related news by Chris Masters

@EmberLinks