ducin ducin - 4 months ago 11
Javascript Question

promise error/exception handling design

I want to create a function that performs async operation and returns a promise. The action is:


  • downloading external content via AJAX

  • if the content can't be downloaded (e.g. invalid URL) -> reject

  • if the content was downloaded successfully, but I can't parse it -> reject

  • otherwise (content was downloaded and parsed successfully) -> resolve



The code I've got now is pretty sttraightforward:

function fetch(hash){
return $.ajax({
method: "GET",
url: baseURL + "/gists/" + hash
}).then(function(response) {
return JSON.parse(response.files['schema.json'].content);
});
}


it's just a jQuery AJAX call that fetches data from github gist. Currently:


  • when the AJAX can't be resolved -> promise gets rejected - OK

  • when the AJAX was resolved and content was parsed correctly -> promise gets resolved - OK

  • however, if the AJAX was resolved, but the content was invalid, the
    JSON.parse
    line throws an error and the promise doesn't get rejected and it should - FAIL



The question is - what is the right design to do that? I could wrap entire thing with a Deferred and handle it manually, but I think there might be an easier solution. Should I do a try-catch? Or something else?

Answer

I could wrap entire thing with a Deferred and handle it manually

That sounds like the deferred antipattern. Don't wrap anything that already uses promises.

I think there might be an easier solution. Should I do a try-catch?

Yes:

.then(function(response) {
  try {
    return JSON.parse(response.files['schema.json'].content);
  } catch (e) {
    return $.Deferred().reject(e);
  }
})

See also Throwing an Error in jQuery's Deferred object.

Or something else?

Actually your original code does work in any reasonable promise implementation, where exceptions become rejections implicitly. It's just jQuery's fail. You might simply want to dodge jQuery's then implementation.

Comments