55

OK, I must be dense since I cannot find anywhere how to get the error status codes when using Node.JS http.get or http.request.

My code:

var deferred = $q.defer();
var req = https.get(options, function(response) {
  var str = '';
  response.on('data', function(chunk) {
    str += chunk;
  });
  response.on('end', function() {
    console.log("[evfService] Got user info: " + str);
    deferred.resolve(str);
  });
});

req.on('error', function(e) {
  deferred.reject(e);
});

In that "req.on" bit, what I want is the http status code (i.e. 401, 403, etc.). What I get is a semi-useless error object that does not give me the code or any reference to the response object.

I have tried intercepting in the function(response) callback, but when there is a 404, it never gets called.

Thanks!

1
  • Did you tried response.statusCode ? Commented May 17, 2014 at 14:28

3 Answers 3

72

Your callback gets called regardless of the response status code from the server, so within your callback, check response.statusCode. That is, a 4xx status code isn't an error at the level you're working at; the server responded, it's just that the server responded by saying the resource wasn't available (etc.)

This is in the documentation but characteristically vague. Here's the example they give, with a comment pointing to the relevant bit:

var https = require('https');

https.get('https://encrypted.google.com/', function(res) {
  console.log("statusCode: ", res.statusCode); // <======= Here's the status code
  console.log("headers: ", res.headers);

  res.on('data', function(d) {
    process.stdout.write(d);
  });

}).on('error', function(e) {
  console.error(e);
});

If you try that with (say) an unknown resource, you'll see statusCode: 404.

So for what you're doing, you may want something like this:

var deferred = $q.defer();

var req = https.get(options, function (response) {
    var str = "";

    if (response.statusCode < 200 || response.statusCode > 299) { // (I don"t know if the 3xx responses come here, if so you"ll want to handle them appropriately
        response.on("data", function() { } ); // ¹
        deferred.reject(/*...with appropriate information, including statusCode if you like...*/);
    }
    else {
        response.on("data", function (chunk) {
            str += chunk;
        });
        response.on("end", function () {
            console.log("[evfService] Got user info: " + str);
            deferred.resolve(str);
        });
    }
});

req.on("error", function (e) {
    deferred.reject(/*...with appropriate information, but status code is irrelevant [there isn"t one]...*/);
});

¹ The empty data event handler in the branch handling non-OK status codes is there because of this note in the documentation:

...if a 'response' event handler is added, then the data from the response object must be consumed, either by calling response.read() whenever there is a 'readable' event, or by adding a 'data' handler, or by calling the .resume() method. Until the data is consumed, the 'end' event will not fire. Also, until the data is read it will consume memory that can eventually lead to a 'process out of memory' error.

Since we're passing a function to https.get, we're hooking the 'response' event, which suggests we need to do one of those things (in this case, I've added a do-nothing data handler). Thanks to Nicolas2bert for pointing that out!.

Sign up to request clarification or add additional context in comments.

4 Comments

Hey there, any ideas on how to perform a retry (if statusCode != 200) , from within the response callback?
@sudosoul: I'd just put the whole thing in a function and, if you want to retry, have that function call itself from the response callback.
In your startus code condition, don't forget to consume response data to free up memory with res.resume(); From: nodejs.org/api/http.html#http_class_http_clientrequest: Also, until the data is read it will consume memory that can eventually lead to a 'process out of memory' error.
@Nicolas2bert - Wow, that's a really surprising requirement. But I read the docs the same way you do, so... Thanks!! I've updated the answer.
15

An error code 400 response is not considered an error by node.js.

Try response.statusCode in this:

request.on('response', function (response) {}); 

Comments

8

Here's a very small example how to get the error code. Just change the https to http and create an error:

var https = require('https')
var username = "monajalal3"
var request = https.get("https://teamtreehouse.com/" + username +".json", function (response) {
    console.log(response.statusCode);
});

request.on("error", function (error) {
    console.error(error.status);
});

Comments

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.