Gergő Tisza has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/198183

Change subject: [WIP] Replace XHR in $.ajax with a proxy object with error 
catching
......................................................................

[WIP] Replace XHR in $.ajax with a proxy object with error catching

Decorate $.ajax to replace the XHR object with a proxy that wraps
the onreadystatechange handler in a try..catch block before
passing it to the real object.

Uses Object.defineProperty, which means no support for IE 8.

TODO: tests

Bug: T92247
Change-Id: I28b95b66e54091054b538102faf2753189001524
---
M resources/src/mediawiki/mediawiki.errorLogging.js
1 file changed, 61 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/83/198183/1

diff --git a/resources/src/mediawiki/mediawiki.errorLogging.js 
b/resources/src/mediawiki/mediawiki.errorLogging.js
index 6dcddc0..2b24137 100644
--- a/resources/src/mediawiki/mediawiki.errorLogging.js
+++ b/resources/src/mediawiki/mediawiki.errorLogging.js
@@ -135,6 +135,67 @@
                                // emulate jQuery.proxy() behavior
                                wrappedHandler.guid = handler.guid = 
handler.guid || $.guid++;
                        } );
+
+                       // There is no easy way to access user callbacks in 
$.ajax as it uses a promise
+                       // mechanism; instead we replace the XHR object with a 
proxy and use that to wrap the
+                       // internal jQuery callback that handles the 
onreadystatechange event. This will miss
+                       // some things such as JSONP requests, but still get 
most things.
+                       $.ajax = mw.errorLogging.decorateWithArgsCallback( 
$.ajax, function ( args ) {
+                               var options, finalOptions;
+
+                               if ( typeof args[0] === 'object' ) {
+                                       options = args[0] || ( args[0] = {} );
+                               } else {
+                                       options = args[1] || ( args[1] = {} );
+                               }
+                               finalOptions = $.ajaxSetup( {}, options );
+
+                               options.xhr = function 
mediaWikiErrorLoggingDecoratedXhrFactory() {
+                                       var proxyXhr = {},
+                                               realXhr = 
finalOptions.xhr.call( this ),
+                                               xhrProperties = ['readyState', 
'status', 'responseText', 'statusText'].concat( finalOptions.xhrFields || [] ),
+                                               xhrMethods = ['open', 
'overrideMimeType', 'setRequestHeader', 'getAllResponseHeaders', 'send', 
'abort'];
+
+                                       try { // IE 8 throws if defineProperty 
is used on non-DOM objects
+                                               $.each( xhrProperties, function 
( _, prop ) {
+                                                       Object.defineProperty( 
proxyXhr, prop, {
+                                                               enumerable: 
true,
+                                                               configurable: 
true,
+                                                               get: function 
() {
+                                                                       return 
realXhr[prop];
+                                                               },
+                                                               set: function ( 
val ) {
+                                                                       
realXhr[prop] = val;
+                                                               }
+                                                       } );
+                                               } );
+
+                                               $.each( xhrMethods, function ( 
_, method ) {
+                                                       if ( realXhr[method] ) {
+                                                               
proxyXhr[method] = function () {
+                                                                       var 
context = this === proxyXhr ? realXhr : this;
+                                                                       return 
mw.errorLogging.safeApply( realXhr[method], context, arguments );
+                                                               };
+                                                       }
+                                               } );
+
+                                               Object.defineProperty( 
proxyXhr, 'onreadystatechange', {
+                                                       enumerable: true,
+                                                       configurable: true,
+                                                       get: function () {
+                                                               return 
realXhr.onreadystatechange;
+                                                       },
+                                                       set: function ( val ) {
+                                                               
realXhr.onreadystatechange = mw.errorLogging.wrap( val, 
'xhr.onreadystatechange' );
+                                                       }
+                                               } );
+
+                                               return proxyXhr;
+                                       } catch ( e ) {
+                                               return realXhr;
+                                       }
+                               };
+                       } );
                }
        };
 }( mediaWiki, jQuery ) );

-- 
To view, visit https://gerrit.wikimedia.org/r/198183
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I28b95b66e54091054b538102faf2753189001524
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: GergÅ‘ Tisza <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to