Error Handling with Rest Adapter and custom error json

I have this Rest adapter

//app/adapters/application.js
import Ember from 'ember';
import DS from 'ember-data'; 

export default DS.RESTAdapter.extend({
    //defaultSerializer: 'JSONSerializer',
    host: 'http://localhost:8081/index.php',
    namespace: 'v1',    
});

I can post to my API fine. The problem is, when I have validation error I cannot receive them in my model. I create a model in response to data sent from component via SendAction() and here is signup route

import Ember from 'ember';

export default Ember.Route.extend({     
    actions:{
        signUp(userInfo){  
            let route = this;
            let user = this.store.createRecord('user', userInfo);
            user.save().then(function(){ //success
                
            }, function(error){ //error  
                alert(error);  // I always get --> Error: The adapter rejected the commit because it was invalid
            });
        }
    }, 
     
});

I always get " Error: The adapter rejected the commit because it was invalid" no matter what I do.

Here is my API error response: [{"field":"first_name","message":"First Name cannot be blank."},{"field":"last_name","message":"Last Name cannot be blank."},{"field":"mobile","message":"Mobile cannot be blank."},{"field":"gender","message":"Gender cannot be blank."},{"field":"username","message":"Username cannot be blank."},{"field":"password","message":"Password cannot be blank."},{"field":"secret_word","message":"Secret Word cannot be blank."},{"field":"created_at","message":"Created At cannot be blank."},{"field":"updated_at","message":"Updated At cannot be blank."}]

I have tried everything I could find in google (SO, Ember forum et al) but with no avail. Here is my latest attempt to get it work.

import Ember from 'ember';
import DS from 'ember-data'; 

export default DS.RESTAdapter.extend({
    //defaultSerializer: 'JSONSerializer',
    host: 'http://localhost:8081/index.php',
    namespace: 'v1',   
  
      parseErrorResponse: function(responseText) {
        let json = responseText;
        let jsonapiError;
        
        try { 
        json = Ember.$.parseJSON(responseText);
        let errors = [];
        for(let i=0; i<json.length; i++)
        {
            let obj = json[i];
            let attrName = obj.field;
            let message = obj.message;
            errors.push({"attribute":attrName, "message":message});
        }
        jsonapiError = {"errors":errors}; 
          
        } catch (e) {}

        return jsonapiError;
      },
     
});

So far I have run out of ideas and would appreciate any pointer or help. TIA, Stefano

It looks like your error responses are formatted incorrectly. The format of the response containing the errors depends on which serializer you are using. You also need to send a 422 http status code. I wrote handling errors and the expected response formats for the different serializers in a blog post: 404 Not Found

As you can see I use JSONSerializer. What is the expected format for it? Is there a function to override so that I can reformat its to make emberjs happy? I would like to avoid reformatting errors on server if that is possible. As for error code its returning correct code that is 422

oops, i linked to the wrong blog post in my last response. it is now fixed. anyways, as i mentioned in the post, the format for JSONSerializer is this:

{
  "errors": {
    "name": [
      "Name is not long enough"
    ]
  }
}

Hi, I have read it and it’s great. However, as I sais above I want to avoid changing API if I can re format the response somewhere in client side. Is it possible to do that in ember, that is to reformat the error object before it bubbles further in ember instead of changing api on server?

Override the extractErrors method in your serializer: RESTSerializer - 4.6 - Ember API Documentation

1 Like

Thanks a lot. I was looking for this for hours and didn’t know it. One more question how do I specify my custom serializer in the adapter?

That does not work. I have tried whatever I could it does not work. This is frustrating. Hours of work just to figure out how to make API work? I think Ember docs need to be updated with the thinking that not everyone is using JSONAPI.

Ended up formatting my error messages to JSONAPI

This is insane.

I tried “handleResponse”, “extractErrors”, none of them works. I haven’t tried to change “JSONAPIAdapter” to “JSONAdapter” because I don’t think Adapter is related to the format of the payload. But the error message is “adapterError” and it’s complaining my error response is not json api compliant. So what is the point of using JSONSerializer if I can only handle non-json-api compliant normal response, but not error response?

I confirm @mtangoo once changing to JSONAP on the server side which is not what I wanted. It works - the errors property appears on the model.

1 Like

I never figured this out. I can’t figure out what I need to do to get ember data to look at error instead of errors. I can’t change my backend.

You should be able to get this to work using the adapter handleResponse method. In the linked docs it says:

Your API might return errors as successful responses with status code 200 and an Errors text or object. You can return a DS.InvalidError or a DS.AdapterError (or a sub class) from this hook and it will automatically reject the promise and put your record into the invalid or error state.

So you could either throw your own error as it suggests or you might (big caveat here: i’ve never tried this) just be able to do something along these lines inside:

if(payload.error) {
  payload.errors = payload.error;
}
this._super(status, headers, payload, requestData);
2 Likes

Thank you so much! I think I just missed it in the earlier deprecation noise.