首页 > 解决方案 > react-admin: 错误: dataProvider 抛出错误。它应该返回一个被拒绝的 Promise - 容易修复吗?

问题描述

在 react-admin 3.2.3 编辑表单中,我需要显示来自不同资源的相关记录(作业记录列表)。这种关系有点奇怪,需要字符串解析,所以我不能只使用内置的ReferenceField. 这就是我尝试使用钩子调用 dataProvidergetList函数的原因。useGetList不幸的是,我在表单呈现时遇到错误:

dataProvider 抛出错误。它应该返回一个被拒绝的 Promise

这是我的自定义数据提供者的 getList 函数:

 getList: (resource, params) => {
        console.log('DataProvider.GetList ');
        console.log(resource);
        console.log(params);
        const { page, perPage } = params.pagination;
        const { field, order } = params.sort;
        const query = {
            ...fetchUtils.flattenObject(params.filter),
            _sort: field,
            _order: order,
            _start: (page - 1) * perPage,
            _end: page * perPage,
        };
        const url = `${getUrl(resource)}?${stringify(query)}`;
        const paging = supportsPaging(resource);

        return httpClient(url).then(
            ({ headers, json }) => {
                var result = [];

                // Implementierung von clientseitigem Paging & Filtering
                var filtered = applyFilter(json, params.filter);
                if (!paging) {
                    filtered=applyPagination(filtered, page, perPage);
                }
                else {
                    result = filtered;
                }

                return {
                    data: result,
                    total: json.length 
                };
            }, ({ reason }) => {

                console.log(reason);
            }).catch((e)=>{
                console.log(e);
            });
    }

我在编辑表单中使用这个自定义组件。

export const CSEJobList = ({ ...props }) => {
    const form = useForm();
    var formdata = form.getState().values;
    console.log("CSEJobList");
    if (formdata && formdata.status && formdata.status.id >= 2) {
        var data = GetJobData({ 'filter': { type: 'abeitsschein_id_' + formdata.id } });
        return data;
    }
    else {
        return <div>Test</div>
    }
};
CSEJobList.defaultProps = { label: 'Arbeitsschein', addLabel: true };

  const GetJobData = (params) => {
        let parms = { "pagination": { "page": 0, "perPage": 25 }, "sort": { "field": "id", "order": "ASC" }, "filter": {} };
        const { data, loading, error } = useGetList('jobs', parms);
        if (loading) { return <LinearProgress />; }
        if (error) { return <p>ERROR</p>; }
        return <p>{data}</p>;
    };

这只是一个基本测试。由于调用导致上述错误,因此尚未实现结果数据的正确显示。

我阅读了有关查询 API 的文档(https://marmelab.com/react-admin/Actions.html#specialized-hooks),摆弄了很多,但由于我对 Promise 的理解有限,我失败了。

有简单的解决方法吗?

更新:

我像这样更改了 dataProvidergetList函数,按照建议返回被拒绝的承诺:

getList: (resource, params) => {
    console.log('DataProvider.GetList ');
    console.log(resource);
    console.log(params);
    const { page, perPage } = params.pagination;
    const { field, order } = params.sort;
    const query = {
        ...fetchUtils.flattenObject(params.filter),
        _sort: field,
        _order: order,
        _start: (page - 1) * perPage,
        _end: page * perPage,
    };
    const url = `${getUrl(resource)}?${stringify(query)}`;
    const paging = supportsPaging(resource);

    return httpClient(url).then(
        ({ headers, json }) => {
            var result = [];

            // Implementierung von clientseitigem Paging & Filtering
            var filtered = applyFilter(json, params.filter);
            if (!paging) {
                filtered=applyPagination(filtered, page, perPage);
            }
            else {
                result = filtered;
            }

            return {
                data: result,
                total: json.length,  // Erfordert nun keinen speziellen Header mehr, CSE-Connect kompatibel
            };
        }, ({ reason }) => {
            return Promise.reject(reason);
        }).catch((e)=>{
            console.log(e);
            return Promise.reject(e);
        });
},

它没有效果。经过一些调试后,我意识到在 GetJobData函数中

if (loading) { return <LinearProgress />; }

导致错误。代码的其他部分完全相同,所以怀疑不是LinearProgress. 我实际上不知道是什么导致了错误。由于超时,调试很难甚至是不可能的。

这是完整的堆栈跟踪:

useDataProvider.js:334 Uncaught Error: The dataProvider threw an error. It should return a rejected Promise instead.
    at performQuery (useDataProvider.js:334)
    at Proxy.<anonymous> (useDataProvider.js:163)
    at JSON.stringify.query (useQueryWithStore.js:116)
    at commitHookEffectList (react-dom.development.js:22030)
    at commitPassiveHookEffects (react-dom.development.js:22064)
    at HTMLUnknownElement.callCallback (react-dom.development.js:336)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:385)
    at invokeGuardedCallback (react-dom.development.js:440)
    at flushPassiveEffectsImpl (react-dom.development.js:25392)
    at unstable_runWithPriority (scheduler.development.js:697)
    at runWithPriority$2 (react-dom.development.js:12149)
    at flushPassiveEffects (react-dom.development.js:25361)
    at performSyncWorkOnRoot (react-dom.development.js:24251)
    at react-dom.development.js:12199
    at unstable_runWithPriority (scheduler.development.js:697)
    at runWithPriority$2 (react-dom.development.js:12149)
    at flushSyncCallbackQueueImpl (react-dom.development.js:12194)
    at flushSyncCallbackQueue (react-dom.development.js:12182)
    at batchedUpdates$1 (react-dom.development.js:24392)
    at Object.notify (Subscription.js:19)
    at Subscription.notifyNestedSubs (Subscription.js:92)
    at Subscription.handleChangeWrapper (Subscription.js:97)
    at dispatch (redux.js:222)
    at middleware.js:22
    at redux-saga-core.esm.js:1410
    at useDataProvider.js:300

标签: javascriptreactjsreact-admin

解决方案


当前实现捕获异常(如果有),并告诉我们不应从数据提供者触发异常,但应将错误作为被拒绝的承诺返回:

错误:dataProvider 引发错误。它应该返回一个被拒绝的 Promise。

让我们看一下当前的代码,它看起来像这样:

} catch (e) {
    if (process.env.NODE_ENV !== 'production') {
        console.error(e);
    }
    throw new Error(
        'The dataProvider threw an error. It should return a rejected Promise instead.'
    );
}

从这里我们可以看到实际错误在此之前被转储到控制台,因为上述关于被拒绝的承诺的错误被触发了。

因此,为了解决这个问题,我们需要将控制台滚动到先前显示的错误并修复它,而不是位于控制台下方和页面本身的 promise 错误。如果可能的话,还要纠正提供者切换到被拒绝的承诺。但是,修复先前的错误就足够了。


推荐阅读