1

I am making http calls in meteor using the npm 'request' package.

I would like to know what type of error object is created when a response.statusCode is not equal to 200? Is this handled by the javascript engine and considered a runtime error?

Or if the statusCode is not equal to 200 is determined by the service provider whether they will create an error object or not?

If the latter, do I create a 'manual error', new Error('throwing my own error for the catch block to handle')

var request = function() {
// HTTP call to server
  },  
  function (error, response, body) {    
  if (!error && response.statusCode === 200) {
    // processed and created data object
      return data
  }
  else {
     return (error) ; // How can I ensure the catch(e) block in the try/catch method will catch the error with an addition of my own 'message'. 
  }
})
};

try {
    request()
}
catch(e) {
  console.log(e)
}

For my scenario, I would like to ensure the catch(e) block will grab this error and I would like to add my own message including the stack trace.

meteorBuzz
  • 3,110
  • 5
  • 33
  • 60
  • Remember _XMLHttpRequest_ is _asynchronous_, you'll get the _error_ callback fired if there was an error, with `this` equal to the request. – Paul S. Feb 28 '15 at 14:17

1 Answers1

1

You don't have to use try..catch unless the operation uses synchronous code (such as making a request using http.get using the meteor http package).

The error code is generally returned by the other server. 200 means its ok. There is a huge list of potential error codes and what they mean.

So the status code will be returned by the callback in the error object but wont be caught by the catch unless its thrown using throw like you've mentioned.

In javascript the problem is when there are callbacks with the error parameter it doesn't actually throw an error that can be caught from where the original function is fired (the request() method you have) if that makes sense.

Even if you use throw in the callback it wont be caught by catch. This is because the callback is fired as an entirely new event. If you want to use the catch technique you need synchronous javascript. I.e with the http package.

meteor add http

Then the code:

try {
    var result = HTTP.get("<url>")
    result.content //this will contain the response
}catch(e) {
    the `e` object will contain the error (if the status code is not 200)
}

You can change the error by throwing your own inside the catch(e) {...} block i.e

...
catch(e) {
    throw new Meteor.Error(500, "Internal Server Error");
}
...

You can throw either a new Error or a new Meteor.Error. The difference being that Meteor.Error will send the error down to the client too as part of the err callback if the piece of code is being run in a method called from the client using Meteor.call e.g

Meteor.call("something", function(err, result) {
    if(err) alert(err.reason);
});

If this calls a method like this:

Meteor.methods({
    something: function() {
        throw new Meteor.Error(500, "This is the message");
    }
});

The client will show a message box saying This is the message as the err.reason. If you throw new Error(.. it will not send the message down to the client and instead the message will be Internal Server Error instead of This is the message

In the method you could have the code that requests the url. If it throws an error within it it would bubble up the stack and find its way to the client.

Tarang
  • 75,157
  • 39
  • 215
  • 276
  • I should have also added, I have used future to make my function seem synchronous. I then run the functions one after the other passing the return result form the previous function into the next. Technically, I am not using callback functions but simply passing the result from one function to the next. Is good practice to handle errors? My previous question demonstrates this with try/catch but I am not using callback... I "return future.return(resultObj)" http://stackoverflow.com/questions/28703715/how-do-you-stop-a-function-when-an-error-object-is-received – meteorBuzz Feb 28 '15 at 14:39
  • Thanks for pointing out Meteor.Error as my functions are executed within a Meteor.call/method. So I would like to pass the error down to the client. – meteorBuzz Feb 28 '15 at 14:40
  • 1
    @CodeCandy Yes I think its the best way to do it. Using futures/Meteor.wrapAsync accounts to the same thing since it would throw the error when the err was fired. The nice thing about throw is it stops further code from executing. I would be careful with this though it needs to take account that execution can stop mid way - not good for financial transactions & payments for example – Tarang Feb 28 '15 at 14:47
  • this is the last extension to my question, why is 'throw' an unexpected token in my code? .."return future.return (throw new Meteor.Error("request was not a 200 response"));" – meteorBuzz Feb 28 '15 at 14:50
  • 1
    @CodeCandy You don't have to return an error, throw it on its own. `throw new Meteor.Error(500, "Error"); return future.return(null)` – Tarang Feb 28 '15 at 15:00
  • All this time I could not figure out why my errors weren't being handle properly. You have reduced my hair balding process!! – meteorBuzz Feb 28 '15 at 15:09