-1

I just notice a weird behavior when dynamically loading scripts with AJAX. I intentionally have a misspelled code that throws an error when it is parsed. Even though the Chrome's console indeed shows the error, the AJAX fail handler is never called.

This is the function that I use to load files:

var load_source = function (path) {
    /* Variable used to determine whether the request was successful */
    var success = false,
        failed;

    $.ajax(
        {
            url: path,
            async: false,
            dataType: 'script',
            method: 'GET'
        }
    ).
        done(function () {
            success = true;
        }).
        fail(function (xhr, status, error) {
            failed = error.stack ? error.stack : error;
        });

    if (failed)
    {
        throw new Error('Unable to load JS file {0}: {1}'.format(path, failed));
    }
}

The only variable provided to the load_source function is "path", which value is a string with the location and name of such a file: "js/myFile.js".

The misspelled part (the part with a typo) of the script to load is this:

var f = function (arg) {
    var param1 = 3,
        param2, /* NOTICE the typo: there is a comma instead of a semicolon */

    if (param1 > arg)
    {
        return true;
    }
    // And more code is coming next...

If I look at the Chrome's console, it shows the error:

Uncaught SyntaxError: Unexpected token if

So far the only way I can catch the error is with the window's onerror event.

So, if that is the only way to catch the error, could you tell me how to stop the "coding" flow, I mean, whenever I call load_source that throws an error (which is handled by the window's onerror function) I want the script to do nothing else:

load_source('js/myFile.js'); // This script will throw the "Uncaught SyntaxError: Unexpected token if" error.
// So I don't want the following code to be executed.
sum(4, 3);
mul(5, 5);
// ...

Can you guys tell me how make the fail event to be triggered?

I also tried with " $(document).ajaxError" but with the same results.

  • Possible duplicate of [Can I throw an exception in Javascript, that stops Javascript execution?](http://stackoverflow.com/questions/9431434/can-i-throw-an-exception-in-javascript-that-stops-javascript-execution) – imtheman Jul 08 '16 at 21:05
  • `async: false` and `dataType: 'script'` don't mix. Because this request is made using a – Kevin B Jul 08 '16 at 21:30
  • @KevinB That is only true for cross-domain scripts. – imtheman Jul 11 '16 at 18:53

2 Answers2

0

It's async stuff :) There is no way that the resource fetching (load_source(url)) is going to be finished before your sum() and mul() functions are executed.

The things you want to make dependable on the successful loading of your remote resource, should be placed in a callback, which is executed after success of the resource fetching.

UPDATE

  • Regarding the "aysnc: false" in your example, and mentioned in the comments: this applies only to the $.ajax() function scope, not to the parent function.
  • Also: is_empty is not part of the standard library, I assume you have defined that function elsewhere?
1sloc
  • 1,180
  • 6
  • 12
  • Not necessarily. He is using `async: false`. – imtheman Jul 08 '16 at 20:52
  • I'm using the async property as false, will be the same result? – DanielYoshua Jul 08 '16 at 20:54
  • But the thing that really maters to me is about the error/exception thrown that is not caught by the fail event – DanielYoshua Jul 08 '16 at 20:57
  • @imtheman async inside of a function doesn't affect the function itself... Checkout my JSFiddle here: https://jsfiddle.net/6rLsaor3/1/ and open up your console. – 1sloc Jul 08 '16 at 21:06
  • 1
    @JethroVanThuyne I was not expecting that... I understand what you mean now. Thank you for that. – imtheman Jul 08 '16 at 21:11
  • @JethroVanThuyne Actually, I was right. The docs state `Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation.` And also, `As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done().` https://api.jquery.com/jQuery.ajax/ – imtheman Jul 08 '16 at 21:19
  • Still, the `async` property in the ajax call applies to the ajax-function scope, not to the calling function. See the forked JSFiddle here, requesting a non-crossdomain script: https://jsfiddle.net/9tr5uy8h/ Same behaviour. – 1sloc Jul 08 '16 at 21:23
  • @JethroVanThuyne That's just not how synchronicity works. https://jsfiddle.net/hdem4ppj/ – imtheman Jul 08 '16 at 21:24
  • Aha. I wasn't aware of the different behaviour between this syntax and the chained methods syntax in the example of OP. Thx! – 1sloc Jul 08 '16 at 21:27
-1

The fail event is being triggered, it's just not stopping the rest of the JS from running. You'd be better off doing some thing like this:

if(load_source('js/myFile.js'))
{
   sum(4, 3);
   mul(5, 5);
}

Then removing your throw in your load_source() function and using return success;, like so:

var load_source = function (path) {
    /* Variable used to determine whether the request was successful */
    var success = false;

    $.ajax(
        {
            url: path,
            async: false,
            dataType: 'script',
            method: 'GET',
            success: function(){
               success = true;
            },
            error: function (xhr, status, error) {
               console.log(error.stack ? error.stack : error);
            }
        }
    );

    return success;
}
imtheman
  • 4,713
  • 1
  • 30
  • 30
  • Hi @imtheman, I edited the code to this: if (failed) { throw new Error('Unable to load JS file {0}: {1}'.format(path, failed)); } and again, even though the console shows the error, the "fail" handler is never triggered ("failed" variable is assigned a value in the "fail" handler ). Also, don't get what you mean with *Then removing your `throw` in your `load_source()` function and using 11return submit;`* – DanielYoshua Jul 09 '16 at 22:08
  • I also change the fail ($.Deferred) for "error" AJAX object propertie but the error is never caught. – DanielYoshua Jul 09 '16 at 22:41
  • Take a look at the changes I made. – imtheman Jul 11 '16 at 18:43
  • The documentation specficially notes that the fail callback may not be called when the data type is set to script or jsonp. – Kevin B Jul 11 '16 at 18:45
  • `fail`, `error: fn`, same thing. it doesn't get called due to the error just not being catchable. – Kevin B Jul 11 '16 at 18:54
  • @KevinB From the docs: `This handler is not called for cross-domain scripts`. this is only true for cross-domain scripts. – imtheman Jul 11 '16 at 18:56
  • imtheman, I tried your code but still the "fail" handler was not triggered. @KevinB, can you point me out to such documentation? Looking at here: "https://api.jquery.com/jquery.getscript/" it is mentioned that one can handle errors with the "fail" handler. – DanielYoshua Jul 11 '16 at 19:22