diff --git a/src/prototype/ajax/request.js b/src/prototype/ajax/request.js index 9bcd689ba..ba35b7325 100644 --- a/src/prototype/ajax/request.js +++ b/src/prototype/ajax/request.js @@ -272,6 +272,10 @@ Ajax.Request = Class.create(Ajax.Base, { **/ success: function() { var status = this.getStatus(); + // status = 0 is also returned upon timeout and connection + // close + if (!status && ('' == this.transport.getAllResponseHeaders())) + return false; return !status || (status >= 200 && status < 300) || status == 304; }, diff --git a/test/unit/ajax_test.js b/test/unit/ajax_test.js index 4b03a2b40..eaa04030a 100644 --- a/test/unit/ajax_test.js +++ b/test/unit/ajax_test.js @@ -387,5 +387,31 @@ new Test.Unit.Runner({ } else { this.info(message); } + }, + + testReportConnectionBroken: function() { + if (this.isRunningFromRake) { + var successTriggered = false, + failureTriggered = false, + exceptionTriggered = false; + + new Ajax.Request("/down", extendDefault({ + onSuccess: function(transport) { + successTriggered = true; + }.bind(this), + onFailure: function(transport) { + failureTriggered = true; + }.bind(this), + onException: function() { + // onException will not trigger for asynchronous + // requests + exceptionTriggered = true; + } + })); + + this.assertEqual(successTriggered, false, 'a request timeout is no success'); + this.assertEqual(failureTriggered, true, 'a request timeout is a failure'); + this.assertEqual(exceptionTriggered, true, 'a synchronous request timeout throws an exception'); + } } });