在通知中显示API错误

时间:2018-08-24 19:07:57

标签: react-admin

我在文档中缺少一些基本知识。收到API验证错误时,我将返回状态代码和消息。看来React-Admin正在将状态代码转换为通用的HTTP错误代码。

我的错误响应。

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

当我的API响应带有该响应时,我在通知框中看到“无法处理的实体”。我正在使用SimpleForm。

我知道状态代码已被识别,因为我已经更改了422,并且它显示了相应的HTTP错误描述。

在文档中说在数据提供者中抛出错误。我已经将Simple Rest数据提供程序移到了我的项目中,并尝试在各个地方抛出错误,但是客户端上没有任何变化。

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

如果您从API中自定义了错误,我们将为您提供任何提示。谢谢。

2 个答案:

答案 0 :(得分:2)

这是实际的错误处理:

  1. 触发获取操作(通常来自数据提供者)时,如果发生错误,则将其捕获并转换为HttpError并重新抛出(source
  2. 在此过程中,HTTP错误消息将变为json.message或响应statusText。 422 HTTP错误在这里变成Unprocessable Entitysource
  3. 然后再次在较高级别捕获错误,以将其转换为redux动作。 (source
  4. 最后,错误被转换为包含错误消息的通知。

因此,为了自定义错误消息,您可以从您的自定义提供程序轻松地做到这一点,首先捕获错误,自定义错误消息,然后再次发送:

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);
            });
    }

    // ...
});

答案 1 :(得分:0)

在后端中,我将响应构造为

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

在客户端,将dataprovider中的convertHTTPResponse修改为:

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)
            }
    }