Commit 01c360f9 authored by jaubourg's avatar jaubourg

Ajax: Protect against exceptions thrown synchronously by xhr.send

When xhr.send throws an exception synchronously, the onerror handler may have
been called already which, unchecked, makes the exception bubble up outside of
jQuery.ajax.

We now catch the exception pre-emptively and only rethrow if we know it hasn't
already been notified through the onerror handler.

Fixes #14683
parent 53e31f47
...@@ -112,10 +112,15 @@ jQuery.ajaxTransport(function( options ) { ...@@ -112,10 +112,15 @@ jQuery.ajaxTransport(function( options ) {
// Create the abort callback // Create the abort callback
callback = xhrCallbacks[ id ] = callback("abort"); callback = xhrCallbacks[ id ] = callback("abort");
// Do send the request try {
// This may raise an exception which is actually // Do send the request (this may raise an exception)
// handled in jQuery.ajax (so no try/catch here)
xhr.send( options.hasContent && options.data || null ); xhr.send( options.hasContent && options.data || null );
} catch ( e ) {
// #14683: Only rethrow if this hasn't been notified as an error yet
if ( callback ) {
throw e;
}
}
}, },
abort: function() { abort: function() {
......
...@@ -1544,6 +1544,36 @@ module( "ajax", { ...@@ -1544,6 +1544,36 @@ module( "ajax", {
}); });
} }
ajaxTest( "#14683 - jQuery.ajax() - Exceptions thrown synchronously by xhr.send should be caught", 4, [
{
url: "data/params_html.php",
method: "POST",
data: {
toString: function() {
throw "Can't parse";
}
},
processData: false,
done: function( data ) {
ok( false, "done: " + data );
},
fail: function( jqXHR, status, error ) {
ok( true, "exception caught: " + error );
strictEqual( jqXHR.status, 0, "proper status code" );
strictEqual( status, "error", "proper status" );
}
},
{
url: "http://domain.org:80d",
done: function( data ) {
ok( false, "done: " + data );
},
fail: function( _, status, error ) {
ok( true, "fail: " + status + " - " + error );
}
}
]);
//----------- jQuery.ajaxPrefilter() //----------- jQuery.ajaxPrefilter()
ajaxTest( "jQuery.ajaxPrefilter() - abort", 1, { ajaxTest( "jQuery.ajaxPrefilter() - abort", 1, {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment