2

I am performing a simple API fetch but I am receiving the following error:

UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot remove headers after they are sent to the client and I am not sure why that is happening:

Code is below and also a print screen of the error is provided. I am not sure if that could be a problem related to the asynchronous behavior of nodejs:

var express = require('express');
var router = express.Router();
var axios = require('axios');
const NodeCache = require('node-cache');
const myCache = new NodeCache();

let hitCount = 0;

/* GET home page. */
router.get('/', function(req, res, next) {
    res.render('index', { title: 'Express' });
});


router.get('/hello', async function(req, res, next) {
    const allData = myCache.get('allData');

    if (!allData) {
        hitCount++;
        console.log(`hit ${hitCount} number of times`);
        try {
            const { data } = await axios.get(
                'https://api.vesselfinder.com/vesselslist?userkey=KEY'
            );
            const [ metaData, ships ] = data;
            myCache.set('allData', data, 70);
            console.log(data + 'This is the data');
            res.send(data);
        } catch (error) {
            res.send(error);
            console.log(error);
        }
    }
    console.log('this is the data:', allData);
    res.send(allData);
});

module.exports = router;

What I have done so far to solve this error was:

I used this source which has a wide explanation of the what the problem could be with a broad explanation of the errors type. However it was not useful to understand what was going on.

Also I found this useful and also this but this last one in particular was an error in the code for a missing statement return. My error seems to be related to a TypeError: data is not iterable but it is not possible because my subscription with the provided is perfectly working.

The closest post I found is this one which basically states that "Sometimes it happens due to asynchronous behavior of nodejs." Now I see this happened to me but I am not sure how this could be solved in this situation.

A log of the error is also shown here in the print screen below for completeness:

error

What can I do to take care of this error? I did a lot of research and I am not sure how to take care of the asynchronous behavior of nodejs. Thank for pointing to the right direction for solving this problem.

1 Answer 1

3

You get this error because you are calling res.send() multiple times:

router.get('/hello', async function(req, res, next) {
    const allData = myCache.get('allData');

    if (!allData) {
        hitCount++;
        console.log(`hit ${hitCount} number of times`);
        try {
            const { data } = await axios.get(
                'https://api.vesselfinder.com/vesselslist?userkey=KEY'
            );
            const [ metaData, ships ] = data;
            myCache.set('allData', data, 70);
            console.log(data + 'This is the data');
            res.send(data); // <-- FIRST TIME
        } catch (error) {
            res.send(error);
            console.log(error);
        }
    }
    console.log('this is the data:', allData);
    res.send(allData); // <-- SECOND TIME
});

Calling res.send() will end the response so you cannot call it again.

You can wrap the second call inside an else condition to ensure that only one is invoked:

router.get('/hello', async function(req, res, next) {
    const allData = myCache.get('allData');

    if (!allData) {
      // ...
    }
    else {
      console.log('this is the data:', allData);
      res.send(allData); // <-- SECOND TIME
    }
});
Sign up to request clarification or add additional context in comments.

7 Comments

Your answer would be better if you showed how this can actually be fixed (hint, it just needs an else statement added or a strategically placed return).
Hi Steve and thanks for reading the question. The reason why I need both is because on the API I have a 1 minute limit per call and they only way I have to by-pass this is by caching the data. So I have to res.send(data); a first time and res.send(allData); a second time to see all the vessels.
As of now if I comment one or the other the program does not work
I see, so the second one is to send the cached data if you have it. As @jfriend00 suggests, you can wrap the second one in an else block.
@SteveHolgado, thank you very much, that was exactly the problem. It took me a really long time to write the question well and in extracting all the information to post and I am glad the question was clear from your side.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.