0

I need to send response after my request to the API and that doesn't work :

    app.post('/auth/login', (req, res, next) => {
    if (req.body.login && req.body.password) {

        var options = { method: 'POST',
        url: 'https://auth.etna-alternance.net/login',
        resolveWithFullResponse: true,
        headers:
        {'cache-control': 'no-cache',
        'content-type': 'multipart/form-data;' },
        formData: { login: req.body.login, password: req.body.password } };
        request(options)
        .then(function (response) {
            console.log(response.body);
            var rawcookies = response.headers['set-cookie'];
            console.log(rawcookies);
            res.sendStatus(200);
        })
        .catch(function (err) {
             res.sendStatus(300);
        });

    } else {
    //  res.sendStatus(400);
    }
    return next();

});

my error :

Unhandled rejection Error: Can't set headers after they are sent.
at validateHeader (_http_outgoing.js:494:11)
at ServerResponse.setHeader (_http_outgoing.js:501:3)
at ServerResponse.header (/Users/nathan/API-Poulette/node_modules/express/lib/response.js:767:10)
at ServerResponse.contentType (/Users/nathan/API-Poulette/node_modules/express/lib/response.js:595:15)
at ServerResponse.sendStatus (/Users/nathan/API-Poulette/node_modules/express/lib/response.js:357:8)
at /Users/nathan/API-Poulette/src/auth.js:41:16
at tryCatcher (/Users/nathan/API-Poulette/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/Users/nathan/API-Poulette/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/Users/nathan/API-Poulette/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/Users/nathan/API-Poulette/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/Users/nathan/API-Poulette/node_modules/bluebird/js/release/promise.js:689:18)
at Async._drainQueue (/Users/nathan/API-Poulette/node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (/Users/nathan/API-Poulette/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues (/Users/nathan/API-Poulette/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:789:20)
at tryOnImmediate (timers.js:751:5)
at processImmediate [as _immediateCallback] (timers.js:722:5)

I use request-promise and I really need to wait and send the API response on my own API

Thank you, for your help

Alicia Sykes
  • 5,997
  • 7
  • 36
  • 64
Dracks
  • 107
  • 8
  • Basically means that you're already in the Body or Finished state, but some function tried to set a header or statusCode. Because your already doing it elsewhere in your code – Alicia Sykes Nov 27 '17 at 15:58
  • This may help: https://stackoverflow.com/questions/7042340/error-cant-set-headers-after-they-are-sent-to-the-client – Alicia Sykes Nov 27 '17 at 15:58
  • yep but i don't call res befor – Dracks Nov 27 '17 at 15:59
  • already read that but i not use res.send or whatever befor the first – Dracks Nov 27 '17 at 16:02
  • Simply put- yes you do. `res.sendStatus` is in your code multiple times!! What have you tried so far? Try debugging, then maybe post some more of your code. Because without more details there couple of similar questions on SO, so take a look at them – Alicia Sykes Nov 27 '17 at 16:02

2 Answers2

2

You are calling res.sendStatus(200) in an async handler. You are also calling next(). The result is that next() is called before your handler has returned. The effect is that whatever middleware is in the chain after this route (maybe just your error handler) is responding to the request before request(options).then() has returned. By the time you hear back from request() you have already sent the headers. The quick answer is to get rid of the next() because there shouldn't be any more middleware after this. You need to either respond to the request or call next(), but not both.

Mark
  • 90,562
  • 7
  • 108
  • 148
0

You're calling next outside the if/else scope.

Request is async so when you call it, it launch the request, then pass to the next operation which is next() until it has the response.

Daphoque
  • 4,421
  • 1
  • 20
  • 31