Display JSON Api conform errors

2019-09-12 07:51发布

问题:

I receive JSON Api conform errors from the backend:

{
  "errors": [
    {
      "status": "400",
      "source": {
        "pointer": "/data/attributes/description"
      },
      "detail": "This field may not be null."
    },
    {
      "status": "400",
      "source": {
        "pointer": "/data/attributes/due-date"
      },
      "detail": "This field may not be null."
    },
    {
      "status": "400",
      "source": {
        "pointer": "/data/attributes/extra-comments"
      },
      "detail": "This field may not be null."
    },
    {
      "status": "400",
      "source": {
        "pointer": "/data/attributes/name"
      },
      "detail": "This field may not be null."
    },
    {
      "status": "400",
      "source": {
        "pointer": "/data/attributes/payment-type"
      },
      "detail": "This field may not be null."
    },
    {
      "status": "400",
      "source": {
        "pointer": "/data/attributes/price"
      },
      "detail": "This field may not be null."
    }
  ]
}

I try to show them in my template, as described in the EmberData documentation:

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

Nothing is shown. I would say the .errors in the model are not populated, but I am not sure how to check this. How can I:

  • display the received ajax reply?
  • make sure that EmberData is processing the reply and populating model.errors?
  • Show the processed model.errors in the console?
  • Show the model and all properties?

In general, I am experiencing that new versions of Ember are very hard to debug. Whenever I show any Ember object in the console, I just see some Computed properties which are not expanded whenever I try to peek into them.

My backend is:

  • Django 1.9
  • with django-rest-framework
  • django-rest-framework-json-api

EDIT

This is the data that I am POSTing to the backend (JSONAPi conform):

{
  "data": {
    "attributes": {
      "name": null,
      "description": null,
      "extra-comments": null,
      "min-price": 30,
      "max-price": 3000,
      "price-step": 10,
      "price": null,
      "payment-type": null,
      "due-date": null
    },
    "relationships": {
      "seller": {
        "data": null
      },
      "artist": {
        "data": null
      },
      "subcategory": {
        "data": null
      }
    },
    "type": "projects"
  }
}

The backend is ok with this, detects the errors, and provides a JSON APi conform errors reply, as specified above.

回答1:

I think I know what's happening (as it happened to me as well).

Change the HTTP error code from 400 to 422 (Unprocessable Entity) and check if it fixes the problem.

Also, looking at the source code for the JSONAPIAdapter (which extends from the RestAdapter) I think I'm right.

isInvalid: function(status, headers, payload) {
   return status === 422;
},

This can be changed to (adapters/application.js):

import DS from 'ember-data';

import config from '../config/environment';

export default DS.JSONAPIAdapter.extend(DataAdapterMixin, {
    host: config.API_HOST,
    namespace: config.API_NAMESPACE,
    isInvalid: function(status, headers, payload) {
        return status === 400 || status === 422;
    },
});


回答2:

For reference, I have done this on the django side:

from rest_framework_json_api.exceptions import exception_handler


def custom_exception_handler(exc, context):
    # DRF returns 400, but EmberData wants 422. I will force a 422, always.
    # Call the rest_framework_json_api's exception handler first,
    # to get the standard error response.
    response = exception_handler(exc, context)
    # TODO: is this correct? 422 in all exception cases?!
    response.status_code = 422
    return response