jenkins-bot has submitted this change and it was merged.
Change subject: Refetch the token when we get a badtoken error
......................................................................
Refetch the token when we get a badtoken error
Intercept badtoken errors, refetch the edit token from the
action=tokens API, and retry the request again. If this fails too,
show the error to the user.
Right now this just shows the good old confirm() dialog if the token
refetch fails; we should probaby give the user a clearer error message
telling them to refresh the page or something.
Bug: 42984
Change-Id: Ib43d1938ffa24bc8d1dc76a300e16e486dabd928
---
M VisualEditor.i18n.php
M VisualEditor.php
M modules/ve/init/mw/targets/ve.init.mw.ViewPageTarget.js
M modules/ve/init/mw/ve.init.mw.Target.js
4 files changed, 104 insertions(+), 6 deletions(-)
Approvals:
Trevor Parscal: Looks good to me, approved
jenkins-bot: Verified
diff --git a/VisualEditor.i18n.php b/VisualEditor.i18n.php
index 522f014..371c342 100644
--- a/VisualEditor.i18n.php
+++ b/VisualEditor.i18n.php
@@ -79,6 +79,7 @@
'visualeditor-inspector-remove-tooltip' => 'Remove',
'visualeditor-viewpage-savewarning' => 'Are you sure you want to go
back to view mode without saving first?',
'visualeditor-loadwarning' => 'Error loading data from server: $1.
Would you like to retry?',
+ 'visualeditor-loadwarning-token' => 'Error loading edit token from
server: $1. Would you like to retry?',
'visualeditor-differror' => 'Error loading data from server: $1.',
'visualeditor-serializeerror' => 'Error loading data from server: $1.',
'visualeditor-saveerror' => 'Error saving data to server: $1.',
diff --git a/VisualEditor.php b/VisualEditor.php
index b3ad6de..a76eaa8 100644
--- a/VisualEditor.php
+++ b/VisualEditor.php
@@ -158,6 +158,7 @@
'visualeditor-notification-restored',
'visualeditor-notification-reported',
'visualeditor-loadwarning',
+ 'visualeditor-loadwarning-token',
'visualeditor-editsummary',
'visualeditor-problem',
'visualeditor-editnotices-tool',
diff --git a/modules/ve/init/mw/targets/ve.init.mw.ViewPageTarget.js
b/modules/ve/init/mw/targets/ve.init.mw.ViewPageTarget.js
index 64b4e1e..240e0a9 100644
--- a/modules/ve/init/mw/targets/ve.init.mw.ViewPageTarget.js
+++ b/modules/ve/init/mw/targets/ve.init.mw.ViewPageTarget.js
@@ -80,6 +80,7 @@
'load': 'onLoad',
'save': 'onSave',
'loadError': 'onLoadError',
+ 'tokenError': 'onTokenError',
'saveError': 'onSaveError',
'editConflict': 'onEditConflict',
'showChanges': 'onShowChanges',
@@ -319,7 +320,7 @@
* Handle failed DOM load event.
*
* @method
- * @param {Object} data HTTP Response object
+ * @param {Object} response HTTP Response object
* @param {string} status Text status message
* @param {Mixed} error Thrown exception or HTTP error string
*/
@@ -334,6 +335,24 @@
};
/**
+ * Handle failed token refresh event.
+ *
+ * @method
+ * @param {Object} response Response object
+ * @param {string} status Text status message
+ * @param {Mixed} error Thrown exception or HTTP error string
+ */
+ve.init.mw.ViewPageTarget.prototype.onTokenError = function ( response, status
) {
+ if ( confirm( ve.msg( 'visualeditor-loadwarning-token', status ) ) ) {
+ this.load();
+ } else {
+ this.activating = false;
+ // User interface changes
+ this.deactivate( true );
+ }
+};
+
+/**
* Handle successful DOM save event.
*
* @method
diff --git a/modules/ve/init/mw/ve.init.mw.Target.js
b/modules/ve/init/mw/ve.init.mw.Target.js
index 8fc90e1..69e59da 100644
--- a/modules/ve/init/mw/ve.init.mw.Target.js
+++ b/modules/ve/init/mw/ve.init.mw.Target.js
@@ -85,6 +85,13 @@
*/
/**
+ * @event tokenError
+ * @param {jqXHR|null} jqXHR
+ * @param {string} status Text status message
+ * @param {Mixed|null} error HTTP status text
+ */
+
+/**
* @event saveError
* @param {jqXHR|null} jqXHR
* @param {string} status Text status message
@@ -133,10 +140,17 @@
this, null, 'Invalid response in response from server',
null
);
} else if ( response.error || data.result === 'error' ) {
- ve.init.mw.Target.onLoadError.call( this, null,
- response.error.code + ': ' + response.error.info,
- null
- );
+ if ( response.error.code === 'badtoken' && !this.retriedToken )
{
+ // Only retry once
+ this.retriedToken = true;
+ // Refresh the edit token and try again
+ this.retryToken();
+ } else {
+ ve.init.mw.Target.onLoadError.call( this, null,
+ response.error.code + ': ' +
response.error.info,
+ null
+ );
+ }
} else if ( typeof data.content !== 'string' ) {
ve.init.mw.Target.onLoadError.call(
this, null, 'No HTML content in response from server',
null
@@ -184,6 +198,37 @@
};
/**
+ * Handle response to a successful edit token refresh request.
+ *
+ * This method is called within the context of a target instance. If
successful the token will
+ * be stored and load() will be called.
+ *
+ * @static
+ * @method
+ * @param {Object} response XHR Response object
+ * @param {string} status Text status message
+ * @emits tokenError
+ */
+ve.init.mw.Target.onToken = function ( response ) {
+ var token = response && response.tokens && response.tokens.edittoken;
+ if ( token ) {
+ this.editToken = token;
+ mw.user.tokens.set( 'editToken', token );
+ this.loading = false; // Otherwise this.load() doesn't do
anything
+ this.load();
+ } else if ( !response.error ) {
+ ve.init.mw.Target.onTokenError.call(
+ this, null, 'Invalid response in response from server',
null
+ );
+ } else {
+ ve.init.mw.Target.onTokenError.call( this, null,
+ response.error.code + ': ' + response.error.info,
+ null
+ );
+ }
+};
+
+/**
* Handle both DOM and modules being loaded and ready.
*
* This method is called within the context of a target instance.
@@ -212,6 +257,21 @@
ve.init.mw.Target.onLoadError = function ( jqXHR, status, error ) {
this.loading = false;
this.emit( 'loadError', jqXHR, status, error );
+};
+
+/**
+ * Handle an unsuccessful token refresh request.
+ *
+ * This method is called within the context of a target instance.
+ *
+ * @param {Object} jqXHR
+ * @param {string} status Text status message
+ * @param {Mixed} error HTTP status text
+ * @emits tokenError
+ */
+ve.init.mw.Target.onTokenError = function ( jqXHR, status, error ) {
+ this.loading = false;
+ this.emit( 'tokenError', jqXHR, status, error );
};
/**
@@ -395,7 +455,6 @@
return '<!doctype html>' + ve.properOuterHtml( newDoc.documentElement );
};
-
/**
* Get DOM data from the Parsoid API.
*
@@ -437,6 +496,24 @@
};
/**
+ * Refresh the edit token, then call load()
+ */
+ve.init.mw.Target.prototype.retryToken = function () {
+ $.ajax( {
+ 'url': this.apiUrl,
+ 'data': {
+ 'action': 'tokens',
+ 'format': 'json'
+ },
+ 'dataType': 'json',
+ 'type': 'GET',
+ 'cache': 'false',
+ 'success': ve.bind( ve.init.mw.Target.onToken, this ),
+ 'error': ve.bind( ve.init.mw.Target.onTokenError, this )
+ } );
+};
+
+/**
* Post DOM data to the Parsoid API.
*
* This method performs an asynchronous action and uses a callback function to
handle the result.
--
To view, visit https://gerrit.wikimedia.org/r/64492
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ib43d1938ffa24bc8d1dc76a300e16e486dabd928
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Catrope <[email protected]>
Gerrit-Reviewer: Catrope <[email protected]>
Gerrit-Reviewer: Esanders <[email protected]>
Gerrit-Reviewer: Krinkle <[email protected]>
Gerrit-Reviewer: Liangent <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: Trevor Parscal <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits