jenkins-bot has submitted this change and it was merged.
Change subject: mw.Upload.BookletLayout: Better handle error messages from
AbuseFilter and TitleBlacklist
......................................................................
mw.Upload.BookletLayout: Better handle error messages from AbuseFilter and
TitleBlacklist
And hopefully, also other extensions, if they follow the format where
result.error.message.key is the key of a message that can be used to report
the error to the user and result.error.message.params is an array of
parameters for it, if any.
The message text is loaded dynamically from the foreign wiki.
Bug: T115260
Bug: T137841
Depends-On: I97c1f5c6bbbdfc0b8ea9914bb075d5299c14df8f (TitleBlacklist)
Depends-On: I5780eae96930211191ecd874aacf53fdacb58f89 (AbuseFilter)
Change-Id: I5d1a289cf3d3b9de53047566172ab19a859e608e
---
M languages/i18n/en.json
M languages/i18n/qqq.json
M resources/Resources.php
M resources/src/mediawiki/api/messages.js
M resources/src/mediawiki/mediawiki.Upload.BookletLayout.js
5 files changed, 74 insertions(+), 45 deletions(-)
Approvals:
MarkTraceur: Looks good to me, approved
Prtksxna: Looks good to me, but someone else must approve
jenkins-bot: Verified
diff --git a/languages/i18n/en.json b/languages/i18n/en.json
index 0d7d047..a35a176 100644
--- a/languages/i18n/en.json
+++ b/languages/i18n/en.json
@@ -4057,7 +4057,6 @@
"mw-widgets-dateinput-placeholder-month": "YYYY-MM",
"mw-widgets-titleinput-description-new-page": "page does not exist yet",
"mw-widgets-titleinput-description-redirect": "redirect to $1",
- "api-error-blacklisted": "Please choose a different, descriptive
title.",
"sessionmanager-tie": "Cannot combine multiple request authentication
types: $1.",
"sessionprovider-generic": "$1 sessions",
"sessionprovider-mediawiki-session-cookiesessionprovider":
"cookie-based sessions",
diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json
index c1e0652..79e9cdd 100644
--- a/languages/i18n/qqq.json
+++ b/languages/i18n/qqq.json
@@ -4238,7 +4238,6 @@
"mw-widgets-dateinput-placeholder-month": "Placeholder displayed in a
date input field when it's empty, representing a date format with 4 digits for
year and 2 digits for month, separated with hyphens (without a day). This
should be uppercase, if possible, and must not include any additional
explanations. If there is no good way to translate it, make this message
blank.",
"mw-widgets-titleinput-description-new-page": "Description label for a
new page in the title input widget.",
"mw-widgets-titleinput-description-redirect": "Description label for a
redirect in the title input widget.",
- "api-error-blacklisted": "Used as error message.\n\nFollowed by the
link {{msg-mw|Mwe-upwiz-feedback-blacklist-info-prompt}}.",
"sessionmanager-tie": "Used as an error message when multiple session
sources are tied in priority.\n\nParameters:\n* $1 - List of dession type
descriptions, from messages like
{{msg-mw|sessionprovider-mediawiki-session-cookiesessionprovider}}.",
"sessionprovider-generic": "Used to create a generic session type
description when one isn't provided via the proper message. Should be phrased
to make sense when added to a message such as
{{msg-mw|cannotloginnow-text}}.\n\nParameters:\n* $1 - PHP classname.",
"sessionprovider-mediawiki-session-cookiesessionprovider": "Description
of the sessions provided by the CookieSessionProvider class, which use HTTP
cookies. Should be phrased to make sense when added to a message such as
{{msg-mw|cannotloginnow-text}}.",
diff --git a/resources/Resources.php b/resources/Resources.php
index 150b8d3..2e22c93 100644
--- a/resources/Resources.php
+++ b/resources/Resources.php
@@ -1298,7 +1298,6 @@
'filename-thumb-name',
'badfilename',
'protectedpagetext',
- 'api-error-blacklisted', // HACK
],
],
'mediawiki.ForeignStructuredUpload.BookletLayout' => [
diff --git a/resources/src/mediawiki/api/messages.js
b/resources/src/mediawiki/api/messages.js
index df21eb2..9ba562e 100644
--- a/resources/src/mediawiki/api/messages.js
+++ b/resources/src/mediawiki/api/messages.js
@@ -44,6 +44,25 @@
*/
loadMessages: function ( messages ) {
return this.getMessages( messages ).then( $.proxy(
mw.messages, 'set' ) );
+ },
+
+ /**
+ * Loads a set of mesages and add them to mw.messages. Only
messages that are not already known
+ * are loaded. If all messages are known, the returned promise
is resolved immediately.
+ *
+ * @param {Array} messages Messages to retrieve
+ * @return {jQuery.Promise}
+ */
+ loadMessagesIfMissing: function ( messages ) {
+ var missing = messages.filter( function ( msg ) {
+ return !mw.message( msg ).exists();
+ } );
+
+ if ( missing.length === 0 ) {
+ return $.Deferred().resolve();
+ }
+
+ return this.getMessages( missing ).then( $.proxy(
mw.messages, 'set' ) );
}
} );
diff --git a/resources/src/mediawiki/mediawiki.Upload.BookletLayout.js
b/resources/src/mediawiki/mediawiki.Upload.BookletLayout.js
index bbd0f1b..31e4492 100644
--- a/resources/src/mediawiki/mediawiki.Upload.BookletLayout.js
+++ b/resources/src/mediawiki/mediawiki.Upload.BookletLayout.js
@@ -260,10 +260,9 @@
layout.emit( 'fileUploaded' );
}, function () {
// These errors will be thrown while the user is on the
info page.
- // Pretty sure it's impossible to get a warning other
than 'stashfailed' here, which should
- // really be an error...
- var errorMessage =
layout.getErrorMessageForStateDetails();
- deferred.reject( errorMessage );
+ layout.getErrorMessageForStateDetails().then( function
( errorMessage ) {
+ deferred.reject( errorMessage );
+ } );
}, function ( progress ) {
var elapsedTime = new Date() - startTime,
estimatedTotalTime = ( 1 / progress ) *
elapsedTime,
@@ -309,8 +308,9 @@
deferred.resolve();
layout.emit( 'fileSaved',
layout.upload.getImageInfo() );
}, function () {
- var errorMessage =
layout.getErrorMessageForStateDetails();
- deferred.reject( errorMessage );
+ layout.getErrorMessageForStateDetails().then(
function ( errorMessage ) {
+ deferred.reject( errorMessage );
+ } );
} );
} );
@@ -322,7 +322,7 @@
* state and state details.
*
* @protected
- * @return {OO.ui.Error} Error to display for given state and details.
+ * @return {jQuery.Promise} A Promise that will be resolved with an
OO.ui.Error.
*/
mw.Upload.BookletLayout.prototype.getErrorMessageForStateDetails =
function () {
var message,
@@ -334,21 +334,34 @@
if ( state === mw.Upload.State.ERROR ) {
if ( !error ) {
// If there's an 'exception' key, this might be
a timeout, or other connection problem
- return new OO.ui.Error(
+ return $.Deferred().resolve( new OO.ui.Error(
$( '<p>' ).msg(
'api-error-unknownerror', JSON.stringify( stateDetails ) ),
{ recoverable: false }
- );
+ ) );
}
- // HACK We should either have a hook here to allow
TitleBlacklist to handle this, or just have
- // TitleBlacklist produce sane error messages that can
be displayed without arcane knowledge
- if ( error.info === 'TitleBlacklist prevents this title
from being created' ) {
- // HACK Apparently the only reliable way to
determine whether TitleBlacklist was involved
- return new OO.ui.Error(
- // HACK TitleBlacklist doesn't have a
sensible message, this one is from UploadWizard
- $( '<p>' ).msg( 'api-error-blacklisted'
),
- { recoverable: false }
- );
+ // Errors in this format are produced by TitleBlacklist
and AbuseFilter. Perhaps other
+ // extensions will follow this format in the future.
+ if ( error.message ) {
+ return this.upload.getApi()
+ .then( function ( api ) {
+ return
api.loadMessagesIfMissing( [ error.message.key ] ).then( function () {
+ if ( !mw.message(
error.message.key ).exists() ) {
+ return
$.Deferred().reject();
+ }
+ return new OO.ui.Error(
+ $( '<p>' ).msg(
error.message.key, error.message.params || [] ),
+ { recoverable:
false }
+ );
+ } );
+ } )
+ .then( null, function () {
+ // We failed when loading the
error message, or it doesn't actually exist, fall back
+ return $.Deferred().resolve(
new OO.ui.Error(
+ $( '<p>' ).msg(
'api-error-unknownerror', JSON.stringify( stateDetails ) ),
+ { recoverable: false }
+ ) );
+ } );
}
if ( error.code === 'protectedpage' ) {
@@ -359,10 +372,10 @@
message = mw.message(
'api-error-unknownerror', JSON.stringify( stateDetails ) );
}
}
- return new OO.ui.Error(
+ return $.Deferred().resolve( new OO.ui.Error(
$( '<p>' ).append( message.parseDom() ),
{ recoverable: false }
- );
+ ) );
}
if ( state === mw.Upload.State.WARNING ) {
@@ -370,63 +383,63 @@
// of importance. For example fixing the thumbnail like
file name
// won't help the fact that the file already exists.
if ( warnings.stashfailed !== undefined ) {
- return new OO.ui.Error(
+ return $.Deferred().resolve( new OO.ui.Error(
$( '<p>' ).msg( 'api-error-stashfailed'
),
{ recoverable: false }
- );
+ ) );
} else if ( warnings.exists !== undefined ) {
- return new OO.ui.Error(
+ return $.Deferred().resolve( new OO.ui.Error(
$( '<p>' ).msg( 'fileexists', 'File:' +
warnings.exists ),
{ recoverable: false }
- );
+ ) );
} else if ( warnings[ 'exists-normalized' ] !==
undefined ) {
- return new OO.ui.Error(
+ return $.Deferred().resolve( new OO.ui.Error(
$( '<p>' ).msg( 'fileexists', 'File:' +
warnings[ 'exists-normalized' ] ),
{ recoverable: false }
- );
+ ) );
} else if ( warnings[ 'page-exists' ] !== undefined ) {
- return new OO.ui.Error(
+ return $.Deferred().resolve( new OO.ui.Error(
$( '<p>' ).msg( 'filepageexists',
'File:' + warnings[ 'page-exists' ] ),
{ recoverable: false }
- );
+ ) );
} else if ( warnings.duplicate !== undefined ) {
- return new OO.ui.Error(
+ return $.Deferred().resolve( new OO.ui.Error(
$( '<p>' ).msg( 'api-error-duplicate',
warnings.duplicate.length ),
{ recoverable: false }
- );
+ ) );
} else if ( warnings[ 'thumb-name' ] !== undefined ) {
- return new OO.ui.Error(
+ return $.Deferred().resolve( new OO.ui.Error(
$( '<p>' ).msg( 'filename-thumb-name' ),
{ recoverable: false }
- );
+ ) );
} else if ( warnings[ 'bad-prefix' ] !== undefined ) {
- return new OO.ui.Error(
+ return $.Deferred().resolve( new OO.ui.Error(
$( '<p>' ).msg( 'filename-bad-prefix',
warnings[ 'bad-prefix' ] ),
{ recoverable: false }
- );
+ ) );
} else if ( warnings[ 'duplicate-archive' ] !==
undefined ) {
- return new OO.ui.Error(
+ return $.Deferred().resolve( new OO.ui.Error(
$( '<p>' ).msg(
'api-error-duplicate-archive', 1 ),
{ recoverable: false }
- );
+ ) );
} else if ( warnings[ 'was-deleted' ] !== undefined ) {
- return new OO.ui.Error(
+ return $.Deferred().resolve( new OO.ui.Error(
$( '<p>' ).msg( 'api-error-was-deleted'
),
{ recoverable: false }
- );
+ ) );
} else if ( warnings.badfilename !== undefined ) {
// Change the name if the current name isn't
acceptable
// TODO This might not really be the best place
to do this
this.setFilename( warnings.badfilename );
- return new OO.ui.Error(
+ return $.Deferred().resolve( new OO.ui.Error(
$( '<p>' ).msg( 'badfilename',
warnings.badfilename )
- );
+ ) );
} else {
- return new OO.ui.Error(
+ return $.Deferred().resolve( new OO.ui.Error(
// Let's get all the help we can if we
can't pin point the error
$( '<p>' ).msg(
'api-error-unknown-warning', JSON.stringify( stateDetails ) ),
{ recoverable: false }
- );
+ ) );
}
}
};
--
To view, visit https://gerrit.wikimedia.org/r/295610
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I5d1a289cf3d3b9de53047566172ab19a859e608e
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Bartosz Dziewoński <[email protected]>
Gerrit-Reviewer: Bartosz Dziewoński <[email protected]>
Gerrit-Reviewer: Edokter <[email protected]>
Gerrit-Reviewer: Jack Phoenix <[email protected]>
Gerrit-Reviewer: Jforrester <[email protected]>
Gerrit-Reviewer: MarkTraceur <[email protected]>
Gerrit-Reviewer: Prtksxna <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits