0

I keep get a header error and I'm not sure where it is coming from:

(node:20635) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
>      at ServerResponse.setHeader (_http_outgoing.js:526:11)
>      at ServerResponse.header (/Users/XXXX/Sites/XXXX/functions/node_modules/express/lib/response.js:771:10)
>      at ServerResponse.send (/Users/XXXX/Sites/XXXX/functions/node_modules/express/lib/response.js:170:12)
>      at ServerResponse.json (/Users/XXXX/Sites/XXXX/functions/node_modules/express/lib/response.js:267:15)
>      at ServerResponse.send (/Users/XXXX/Sites/XXXX/functions/node_modules/express/lib/response.js:158:21)
>      at /Users/XXXX/Sites/XXXX/functions/src/controllers/embassies.js:95:48
>      at processTicksAndRejections (internal/process/task_queues.js:97:5)
>  (node:20635) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
>  (node:20635) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

I'm using Axios to call the external Mapbox APIs. I've tried .catch() on everything but I can't shake this error. I'm wondering if I can't do two external calls within the same function but I can't confirm that — is this possible?

I'm trying to update the restaurant with the new details and once update I want to get the latitude and longitude of the address and save it to the database as well. Once that is done, I want to get the image of the Map using the latitude and longitude and then upload this image to the Firebase storage.

Here is my functions code:

static update(collectionData, storage, country, restaurant, body, res) {
        const countryData = collectionData.where('countryCode', '==', country.toUpperCase()).limit(1);

        return countryData.get()
            .then(data => {
                const restaurantData = data.docs[0].ref.collection('restaurants');
                return restaurantData.where('country', '==', restaurant.toUpperCase()).limit(1);
            })
            .then(restaurantCollection => {
                return restaurantCollection.get()
                    .then(restaurants => {
                        restaurants.forEach(doc => {
                            let restaurant = doc.data();

                            // Set the document with the body data
                            return doc.ref.set(body, {merge: true})
                                .then(() => {
                                    let address = restaurant.addressLine1 + ' ' + (restaurant.addressLine2 ? (restaurant.addressLine2 + ' ') : "") + restaurant.suburb + ' ' + (restaurant.state ? (restaurant.state + ' ') : "") + (restaurant.postcode ? (restaurant.postcode + ' ') : "") + restaurant.country;

                                    return axios.get('https://api.mapbox.com/geocoding/v5/mapbox.places/' + address + '.json?limit=1&types=address&access_token=XXXXXX')
                                        .then(function (response) {
                                            doc.ref.set({
                                                "longitude": response.data.features[0].geometry.coordinates[0],
                                                "latitude": response.data.features[0].geometry.coordinates[1]
                                            }, {merge: true});

                                            return response.data.features[0].geometry.coordinates;
                                        })
                                        .catch(function (error) {
                                            return res.send(error);
                                        });
                                })
                                .then(geoData => {
                                    let marker = 'https%3A%2F%2Fuploads-ssl.webflow.com%XXXXXX%XXXXXX-marker.png';

                                    console.log(geoData);

                                    return axios.get('https://api.mapbox.com/styles/v1/XXX/XXXX/static/url-' + marker + '(' + geoData[0] + ',' + geoData[1] + ')' + '/' + geoData[0] + ',' + geoData[1] + ',14,0/800x800?access_token=XXXXXX')
                                        .then(function (response) {
                                            storage.ref('restaurant-maps/' + country + '-' + restaurant.toLowerCase() + '.png').put(response)
                                                .then(() => {
                                                    console.log('Uploading Map: restaurant-maps/' + country + '-' + restaurant.toLowerCase() + '.png');
                                                })
                                                .catch(function (error) {
                                                    return res.send(error);
                                                });
                                        })
                                        .catch(function (error) {
                                            return res.send(error);
                                        });
                                })
                                .catch(err => {
                                    return res.send(err);
                                });
                        });

                        return res.status(200).send('restaurant has been updated!');
                    })
                    .catch(err => {
                        return res.status(404).send('Error finding restaurants for this country: ' + err);
                    });

            })
            .catch(err => {
                return res.status(404).send('Error updating restaurant for this country: ' + err);
            });
    }
aszet
  • 83
  • 7
  • Not sure but in case you didn't know there is a JS SDK for the Mapbox APIs https://github.com/mapbox/mapbox-sdk-js, though you can still use the APIs directly if you preferred. – AndrewHarvey May 30 '20 at 03:05

1 Answers1

0

I believe your issue is that you are sending more than one response per request. You can find a detailed explanation here on how to handle these HTTP request errors on this SO post here

MaryM
  • 164
  • 4