Curtis Olson
Curtis Olson

Reputation: 315

Show API error in notification

I'm missing something basic in the docs. When I get an API validation error, I'm returning a status code and message. It appears that React-Admin is translating the status code to a generic HTTP error code.

My error response.

{"error":
    {"statusCode":422,
    "name":"Error",
    "message":"User with same first and last name already on team."}
}

When my API response with that response, I'm seeing "Unprocessable Entity" in the notification box. I'm using SimpleForm.

I know the status code is being recognized because I've changed the 422 and it shows the corresponding HTTP error description.

In the docs it says to throw and error in your data provider. I've moved that the Simple Rest data provider into my project and have tried throwing errors are various places, but nothing changes on the client.

https://marmelab.com/react-admin/DataProviders.html#error-format

If you have customized error from your API, I'd appreciated any hints you can give. Thx.

Upvotes: 10

Views: 6387

Answers (2)

Kmaschta
Kmaschta

Reputation: 2429

Here is the actual error processing:

  1. When a fetch is triggered (usually coming from the data provider), if an error happen, it is caught and transformed into an HttpError and re-thrown (source)
  2. In the process, the HTTP Error message becomes either the json.message or the response statusText. It's here that a 422 HTTP Error becomes Unprocessable Entity (source)
  3. Then the error is caught again at a higher level to be transformed into a redux action. (source)
  4. Finally, the error is transformed into a notification containing the error message.

So, in order to customize your error message, you can easily do that from your custom provider by catching the error in the first place, customizing the error message, and send it again:

const dataProvider = (type, resource, params) => new Promise((resolve, reject) => {
    if (type === 'GET_LIST' && resource === 'posts') {
        return fetch(...args)
            .then(res => res.json())
            .then(json => {
                if (json.error) {
                    // The notification will show what's in { error: "message" }
                    reject(new Error(json.error.message));
                    return;
                }

                resolve(json);
            });
    }

    // ...
});

Upvotes: 11

iamwaseem99
iamwaseem99

Reputation: 43

in Backend, I structure the response as

res.json({status:400,message:"Email Address is invalid!"})

In Client side, modify the convertHTTPResponse in dataprovider as:

const convertHTTPResponse = (response, type, resource, params) => {
    const { headers, json } = response;
    switch (type) {
        case GET_LIST:
        case GET_MANY_REFERENCE:
            if(json.status === 200){
                if (!headers.has('content-range')) {
                    throw new Error('The Content-Range header is missing in the HTTP Response.);
                }
                return {
                    data: json.docs,
                    total: parseInt(
                        headers
                            .get('content-range')
                            .split('/')
                            .pop(),
                        10
                    ),
                };
            }else{
                throw new Error(json.message)
            }

        default:
            if(json.status === 200){
                return { data: json.docs };
            }else{
                throw new Error(json.message)
            }
    }

Upvotes: 0

Related Questions