Bia
Bia

Reputation: 183

Request Promise unhandled reject

Basically I have to do a POST request an try to save this data on an API after I get the return of this POST and save this information on a database.

So, I did a call to a promise (saveProcessedData or saveErrorData) inside another promise, works as expected although is trowing out a warning:

Unhandled rejection StatusCodeError: 400

const sendData = async(data, item) => {

    let payload = [],
        dataProcessed = [];

    let options = { 
        method: data.endpoint.method,
        url: api._url + data.endpoint.url,
        headers: 
        { 
            'Postman-Token': api._postmanToken,
            'cache-control': api._cache,
            'x-ccasset-language': 'en',
            Authorization: data.token
        },
        body: item,
        json: true 
    };

    return new Promise((resolve, reject) => {
        api._request(options, async (error, response, body) => {
            if(!response.body.errorCode && response.statusCode === 200) {
                payload = {
                    body: response.body,
                    type: data.req.body.type
                }
                dataProcessed = await db.saveProcessedData(payload);
            } else {
                payload = {
                    body: item,
                    type: data.req.body.type,
                    description: response.body.message
                }
                dataProcessed = await db.saveErrorData(payload);
            }

            if (error) {
                reject(error)
            }

            resolve(dataProcessed);
        });
    });
}

How Can I catch this error?

Upvotes: 0

Views: 1285

Answers (3)

Michael Rodriguez
Michael Rodriguez

Reputation: 2176

When you call sendData() you can use Promise.prototype.catch() to catch exceptions that occurred in your promise, including any reject():

sendData(myData, myItem)
    .then(result => {
        //do stuff with result 
    }
    .catch(error => {
        //handle error
    };

Upvotes: 1

Marcos Casagrande
Marcos Casagrande

Reputation: 40404

It's better if you don't mix callbacks & promises the way you're doing it. You're getting that error because you're not handling the errors correctly inside api._request callback.

Wrap your code inside the callback in a try/catch, because that's how you handle exceptions in async functions.

new Promise(async resolve => {
    await Promise.reject() // Unhandled Promise Rejection
}).catch(console.error) // not catched

Should be:

new Promise(async resolve => {
    try {
       await Promise.reject()
       resolve();
    } catch(e) {
       reject(e)
    }

}).catch(console.error) // catched

In any case, since you're wrapping api._request in a Promise, it would be better to do:


const sendData = async(data, item) => {

    // ...

    const { error, response, body } = await new Promise((resolve, reject) => {
        api._request(options, (error, response, body) => resolve({ error, response, body }))
    })

    if(!response.body.errorCode && response.statusCode === 200) {
        payload = {
            body: response.body,
            type: data.req.body.type
        }
        dataProcessed = await db.saveProcessedData(payload);
    } else {
        payload = {
            body: item,
            type: data.req.body.type,
            description: response.body.message
        }
        dataProcessed = await db.saveErrorData(payload);
    }

    return dataProcessed;
}

And attach a .catch handler to .sendData

Aside from that in your code, if error is truthy, you're rejecting and then resolving, nothing wrong will happen in that case, but it's better to use return reject(). A Promise, can't be rejected & resolved.

if (error) {
   return reject(error)
}

resolve(dataProcessed);

If you're using request, you can use request-promise or request-promise-native which are Promise wrappers around request package.

Upvotes: 2

Yaroslav Gaponov
Yaroslav Gaponov

Reputation: 2099

Just formatting

const sendData = async (data, item) => {

    const options = {
        method: data.endpoint.method,
        url: api._url + data.endpoint.url,
        headers: {
            'Postman-Token': api._postmanToken,
            'cache-control': api._cache,
            'x-ccasset-language': 'en',
            Authorization: data.token
        },
        body: item,
        json: true
    };

    return Promise.resolve()
        .then(() =>
            new Promise((resolve, reject) => {
                api._request(options, (error, response) => {
                    if (!response.body.errorCode && response.statusCode === 200) {
                        return resolve(
                            {
                                body: response.body,
                                type: data.req.body.type
                            }
                        );

                    }
                    return reject({
                        body: item,
                        type: data.req.body.type,
                        description: error || response.body.message
                    });
                })
            }))
        .then(payload => db.saveProcessedData(payload))
        .catch(payload => db.saveErrorData(payload))
}

Upvotes: 1

Related Questions