react-admin: ERROR: The dataProvider threw an error. It should return a rejected Promise instead - easy fix?
Asked Answered
S

3

9

In an react-admin 3.2.3 edit form I need to show related records (the list of job records) from a different resource. The relation is a bit weird and requires string parsing so I can't just use the built-in ReferenceField. That's why I am trying to call the dataProvider's getList function using the useGetList hook. Unfortunately I get an error on form rendering:

The dataProvider threw an error. It should return a rejected Promise instead

This is the getList function of my custom dataprovider:

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

I use this custom component in the edit form.

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

This is just a basic test. Proper display of result data is not implemented yet since the call results in the mentioned error.

I read the documentation (https://marmelab.com/react-admin/Actions.html#specialized-hooks) about querying the API, fiddled around a lot, but I fail because of my limited understanding of promises.

Is there an easy fix?

Update:

I changed the dataProvider getList function like so, return rejected promises as suggested:

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

It had no effect. After some debugging I realized that in the GetJobData function the line

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

causes the error. Exactly the same works in other parts of the code, so the suspect is not LinearProgress. I actually have no Idea what causes the error. Debugging is hard to impossible because of timeouts.

This is the full stack trace:

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
Shortchange answered 25/2, 2020 at 16:19 Comment(4)
what import do you use for LinearProgress?Sascha
I use LinearProgress from react-adminShortchange
There is no reason this component can fail... So I have no idea why your code doesn't work.Sascha
LinearProgress works fine on other parts of the code, I have no Idea why this happens.Shortchange
J
3

Current implementation catchs the exception, if any, and say us that the exception should not be fired from the data provider, but the error should be returned as rejected promise:

Error: The dataProvider threw an error. It should return a rejected Promise instead.

Let's take a look to current code, it looks like this:

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

From this we can see that actual error is dumped to the console just before that as the mentioned error about rejected promise is fired.

Thus, to solve the problem, we need to scroll the console to the previously displayed error and fix it instead of the promise error, which is located below in the console and on the page itself. And if possible, also correct the provider to switch to the rejected promise. However, fixing the previous error will suffice.

Jackdaw answered 21/3, 2020 at 21:7 Comment(0)
H
0

if an error occurs, your dataProvider should return the following value:

import { HttpError } from 'react-admin'
...
return Promise.reject(new HttpError(message, status, body))
Hooghly answered 27/2, 2020 at 7:42 Comment(1)
Thanks, I tried your suggestion, but it seems that the error is caused somewhere else. See my update.Shortchange
I
0

This is unrelated to OP's problem but I got this issue when I miss typed filters to filter:

<List filters={myPostFilters}>  // this should be plural "filters"
   // ...
</List>

If singular, somehow this will result in the same error as OP's.

Intern answered 26/5, 2022 at 12:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.