What is the proper JSONAPI response for a 404 not found?


#1

I’m using ember-cli-mirage and I’m getting an adapter error when I try to simulate the backend response when a model cannot be found.

Error while processing route: user Adapter operation failed Error: Adapter operation failed

I haven’t been able to find a authoritative source of what the JSONAPI response to a request for a missing resource should be.

Should it simply have the 404 response code and no content? Should I send something in the { errors: [] } key?

This is the route:

import Ember from 'ember';

export default Ember.Route.extend({
  errorRedirectTo: 'users',
  model: function(){
    return this.store.createRecord('user');
  }
});
// app/mirage/config.js
this.get('/users/:id', (db, request) => {
  let user = db.users.find(request.params.id);
  if (user) {
    return jsonapi.serializeOne(user); // works
  } else {
    return new Mirage.Response(404, null, null);
  }
});

#2

We are seeing the same issue here! Not using mock-data but our live-api, which sometimes results in 404:s giving this error.


#3

Hmm, then it’s a ember data issue?


#4

I think what you’re looking for is implementing the error action on your route: http://guides.emberjs.com/v2.0.0/routing/loading-and-error-substates/#toc_the-code-error-code-event


#5

@rytis there must be a way of having this lower? Most of my data is prefilled when booting the app and then loaded only sometimes, not connected to a route. :frowning:


#6

I believe the following should work if you want to handle errors on individual basis:

this.store.find('pizza', 1).catch(function(){
    // Handle the error
});

Edit: I haven’t tried this myself, I’m usually ok with an error handler in my route


#7

@rytis I understand, that could be implemented on every fetch I do have - but it seems that it should be much easier to catch this error generally in the adapters handleResponse method?

My app should already support this - but this error still shows up. :frowning:


#8

Also see https://github.com/json-api/json-api/pull/828 (disclaimer is me)


#9

The proper way is to handleResponse in your adapter and modify the payload to have an error-object.

The solution below is not intended for production and is a rudimentary way to show how how to do this:

    /**
 * handleResponse from backend, check for errors
 * @param  {[type]} status  [description]
 * @param  {[type]} headers [description]
 * @param  {[type]} payload [description]
 * @return {[type]}         [description]
 */
handleResponse: function(status, headers, payload) {

    // Fix payload if not present
    if (typeof payload === 'undefined') {
        payload = {};
    }

    // If we have an error
    if (String(status).charAt(0) === '4' || String(status).charAt(0) === '5') {

        // Push error in payload if not exists
        if (!payload.hasOwnProperty('errors')) {
            payload = {}; // Clear payload
            payload.errors = []; // Set empty array
        }

    }

    // Everything seems fine, continue
    return this._super(status, headers, payload);
}

#10

Thanks - I modified the simulated response to include a errors array - don’t really want to mess with the JSONAPI adapter - especially not since the API itself is under my control.

return new Mirage.Response(404, {"Content-Type": "application/json"}, { errors: [] });