Catch statement does not catch thrown error

64,020

Solution 1

The reason why your try catch block is failing is because an ajax request is asynchronous. The try catch block will execute before the Ajax call and send the request itself, but the error is thrown when the result is returned, AT A LATER POINT IN TIME.

When the try catch block is executed, there is no error. When the error is thrown, there is no try catch. If you need try catch for ajax requests, always put ajax try catch blocks inside the success callback, NEVER outside of it.

Here's how you should do it:

success: function (result) {
    try {
      result = jQuery.parseJSON(result);

      if (!result.data.email) {
         throw ('New exception');
      }
      console.log(result);
      jQuery('.email').html(result.data.email);
    } catch (exception) {
      console.error("bla");
    };
}

Solution 2

Due to the asynchronous nature of the callback methods in javascript, the context of the function throwing the error is different compared to the original one. You should do this way:

success: function (result) {
  try {
    result = jQuery.parseJSON(result);
    if(!result.data.email){
      throw ('New exception');
    }
    console.log(result);
    jQuery('.email').html(result.data.email);
  }
  catch(err) {
    // Dealing with the error
  }
}

I would suggest you to have a look at this excellent article about the (very particular) contexts, closures and bindings in Javascript.

Solution 3

The problem is that ajax is asynchronous by definition. Your exception does not get thrown from within the $.ajax function, but from the callback function on success (which is triggered at a later time).

You should give an error: function(data) {} parameter to it as well, to handle server response errors, and furthermore you should place the try/catch block inside the callback function.

If you really want to catch it outside the callback, then you should consider calling a function rather than throwing an exception, because I don't see how it can be done.

Share:
64,020
Xenology
Author by

Xenology

Updated on May 11, 2020

Comments

  • Xenology
    Xenology about 4 years

    For some reason this code gives me an uncaught exception error. It seems the catch block is not catching the error. Are try catch blocks scoped in such a way that I cannot throw an error in a nested function, and then expect it to be caught by a catch statement scoped higher up the chain? Some of the sensitive data with in the application that i'm working in has been removed, but it expected that leadInfo[ 0 / 1] would be a 32 character alpha numeric string that I pull from URL parameters.

    The underlying issue here is with my AJAX call returning an error from the API and that error not being handled properly within the application. Hence the need for the throw statement. The AJAX call completes fine, and returns a JSON object that does not contain the email address as a property, so I need to handle that in a way that changes the page to reflect that.

        jQuery(document).ready(function(){
            try {
                url = "http://api.com/api/v1/lead/" + leadInfo[1]
    
                jQuery.ajax({
                    type: 'GET',
                    contentType: 'application/json',
                    url: url,
                    dataType : 'jsonp',
                    success: function (result) {
    
                        result = jQuery.parseJSON(result);
    
                        if(!result.data.email){
                            throw ('New exception');
                        }
                        console.log(result);
                        jQuery('.email').html(result.data.email);
                    }
                });
    
    
                jQuery('.surveryButton').click(function(){
                    window.location.replace("http://" + pgInventory.host + pgInventory.path + leadInfo[0] + "&curLeadId=" + leadInfo[1] + "&curViewedPages=0");
                });
            }
            catch(err) {
                jQuery('.email').html('your e-mail address');
                jQuery('#arrowContent').remove();
            }
    });