From e8d7173e9f3215f06c65f7e329152066f6da92ce Mon Sep 17 00:00:00 2001 From: Matthias Mullie Date: Sun, 8 Jan 2017 20:10:34 +0100 Subject: [PATCH] Use parsed HTML error responses instead of api-error-* There is no point in keeping these api-error- messages. They were originally introduced in UploadWizard, then moved to core, where nothing else (apart from some in BookletLayout) uses them. They are mostly duplicates of other messages in core, and these are very easy to miss when updating a message in core. Instead of building the messages on the frontend, we're much better off requesting a parsed error response from the API right away. This also lets us get rid of sime hacks (e.g. for AbuseFilter) And then a few other api-error-* messages have been removed in favor of their alternatives (which are also used elsewhere) And stashfailed is not a warning. Maybe it was at some point, but stashfailed now dies with an error. Bug: T47843 Change-Id: I41d88e2aad308a1fecd10d97085345a17d0c3603 --- languages/i18n/en.json | 46 +---------- languages/i18n/qqq.json | 44 ---------- resources/Resources.php | 55 ++----------- ...i.ForeignStructuredUpload.BookletLayout.js | 9 ++- .../mediawiki.Upload.BookletLayout.js | 81 +++++++------------ 5 files changed, 44 insertions(+), 191 deletions(-) diff --git a/languages/i18n/en.json b/languages/i18n/en.json index 1e37d40baf..0d9b1eefa7 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -3966,56 +3966,12 @@ "feedback-useragent": "User agent:", "searchsuggest-search": "Search {{SITENAME}}", "searchsuggest-containing": "containing...", - "api-error-autoblocked": "Your IP address has been blocked automatically, because it was used by a blocked user.", - "api-error-badaccess-groups": "You are not permitted to upload files to this wiki.", "api-error-badtoken": "Internal error: Bad token.", - "api-error-blocked": "You have been blocked from editing.", - "api-error-copyuploaddisabled": "Uploading by URL is disabled on this server.", - "api-error-duplicate": "There {{PLURAL:$1|is another file|are some other files}} already on the site with the same content.", - "api-error-duplicate-archive": "There {{PLURAL:$1|was another file|were some other files}} already on the site with the same content, but {{PLURAL:$1|it was|they were}} deleted.", - "api-error-empty-file": "The file you submitted was empty.", "api-error-emptypage": "Creating new, empty pages is not allowed.", - "api-error-fetchfileerror": "Internal error: Something went wrong while fetching the file.", - "api-error-fileexists-forbidden": "A file with name \"$1\" already exists, and cannot be overwritten.", - "api-error-fileexists-shared-forbidden": "A file with name \"$1\" already exists in the shared file repository, and cannot be overwritten.", - "api-error-file-too-large": "The file you submitted was too large.", - "api-error-filename-tooshort": "The filename is too short.", - "api-error-filetype-banned": "This type of file is banned.", - "api-error-filetype-banned-type": "$1 {{PLURAL:$4|is not a permitted file type|are not permitted file types}}. Permitted {{PLURAL:$3|file type is|file types are}} $2.", - "api-error-filetype-missing": "The filename is missing an extension.", - "api-error-hookaborted": "The modification you tried to make was aborted by an extension.", - "api-error-http": "Internal error: Unable to connect to server.", - "api-error-illegal-filename": "The filename is not allowed.", - "api-error-internal-error": "Internal error: Something went wrong with processing your upload on the wiki.", - "api-error-invalid-file-key": "Internal error: File was not found in temporary storage.", - "api-error-missingparam": "Internal error: Missing parameters on request.", - "api-error-missingresult": "Internal error: Could not determine if the copy succeeded.", - "api-error-mustbeloggedin": "You must be logged in to upload files.", - "api-error-mustbeposted": "Internal error: Request requires HTTP POST.", - "api-error-noimageinfo": "The upload succeeded, but the server did not give us any information about the file.", - "api-error-nomodule": "Internal error: No upload module set.", - "api-error-ok-but-empty": "Internal error: No response from server.", - "api-error-overwrite": "Overwriting an existing file is not allowed.", - "api-error-ratelimited": "You're trying to upload more files in a short space of time than this wiki allows.\nPlease try again in a few minutes.", - "api-error-stashfailed": "Internal error: Server failed to store temporary file.", "api-error-publishfailed": "Internal error: Server failed to publish temporary file.", - "api-error-stasherror": "There was an error while uploading the file to stash.", - "api-error-stashedfilenotfound": "The stashed file was not found when attempting to upload it from the stash.", - "api-error-stashpathinvalid": "The path at which the stashed file should have been found was invalid.", - "api-error-stashfilestorage": "There was an error while storing the file in the stash.", - "api-error-stashzerolength": "The server could not stash the file, because it had zero length.", - "api-error-stashnotloggedin": "You must be logged in to save files in the upload stash.", - "api-error-stashwrongowner": "The file you were attempting to access in the stash does not belong to you.", - "api-error-stashnosuchfilekey": "The file key you were attempting to access in the stash does not exist.", - "api-error-timeout": "The server did not respond within the expected time.", - "api-error-unclassified": "An unknown error occurred.", - "api-error-unknown-code": "Unknown error: \"$1\".", - "api-error-unknown-error": "Internal error: Something went wrong when trying to upload your file.", + "api-error-stashfailed": "Internal error: Server failed to store temporary file.", "api-error-unknown-warning": "Unknown warning: \"$1\".", "api-error-unknownerror": "Unknown error: \"$1\".", - "api-error-uploaddisabled": "Uploading is disabled on this wiki.", - "api-error-verification-error": "This file might be corrupt, or have the wrong extension.", - "api-error-was-deleted": "A file of this name has been previously uploaded and subsequently deleted.", "duration-seconds": "$1 {{PLURAL:$1|second|seconds}}", "duration-minutes": "$1 {{PLURAL:$1|minute|minutes}}", "duration-hours": "$1 {{PLURAL:$1|hour|hours}}", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index 2f16979702..42c4ae5f65 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -4151,56 +4151,12 @@ "feedback-useragent": "A label denoting the user agent in the feedback that is posted to the feedback page.\n{{Identical|User agent}}", "searchsuggest-search": "Greyed out default text in the simple search box in the Vector skin. (It disappears and lets the user enter the requested search terms when the search box receives focus.)\n{{Identical|Search}}", "searchsuggest-containing": "Label used in the special item of the search suggestions list which gives the user an option to perform a full text search for the term.", - "api-error-autoblocked": "API error message that can be used for client side localisation of API errors.\n\nCf. {{msg-mw|Autoblockedtext}}.", - "api-error-badaccess-groups": "API error message that can be used for client side localisation of API errors.", "api-error-badtoken": "API error message that can be used for client side localisation of API errors.", - "api-error-blocked": "API error message that can be used for client side localisation of API errors.", - "api-error-copyuploaddisabled": "API error message that can be used for client side localisation of API errors.", - "api-error-duplicate": "API error message that can be used for client side localisation of API errors. Parameters:\n* $1 - a number of files", - "api-error-duplicate-archive": "API error message that can be used for client side localisation of API errors. Parameters:\n* $1 - a number of files", - "api-error-empty-file": "API error message that can be used for client side localisation of API errors.", "api-error-emptypage": "API error message that can be used for client side localisation of API errors.", - "api-error-fetchfileerror": "API error message that can be used for client side localisation of API errors.", - "api-error-fileexists-forbidden": "API error message that can be used for client side localisation of API errors.\n\nParameters:\n* $1 - filename\nSee also:\n* {{msg-mw|Api-error-fileexists-shared-forbidden}}", - "api-error-fileexists-shared-forbidden": "API error message that can be used for client side localisation of API errors.\n\nParameters:\n* $1 - filename\nSee also:\n* {{msg-mw|Api-error-fileexists-forbidden}}", - "api-error-file-too-large": "API error message that can be used for client side localisation of API errors.", - "api-error-filename-tooshort": "API error message that can be used for client side localisation of API errors.", - "api-error-filetype-banned": "API error message that can be used for client side localisation of API errors.", - "api-error-filetype-banned-type": "API error message that can be used for client side localisation of API errors.\n\n* $1 is the extension(s) of the file which cannot be uploaded\n* $2 is the list of file extensions that can be uploaded (Example: ''png, gif, jpg, jpeg, ogg, pdf, svg.'')\n* $3 is the number of allowed file formats (to be used for the PLURAL function)\n* $4 is the number of extensions that could not be uploaded (to be used for the PLURAL function)", - "api-error-filetype-missing": "The word \"extension\" refers to the part behind the last dot in a file name, that by convention gives a hint about the kind of data format which a files contents are in.", - "api-error-hookaborted": "The word \"extension\" here refers to a [[:mw:Manual:Extensions|MediaWiki Extension]] which extends the functionality of the basic wiki by adding something to its capabilities. \"… aborted by an extension\" implies that an operation could not be performed successfully or was not allowed to continue to its intended end.", - "api-error-http": "API error message that can be used for client side localisation of API errors.", - "api-error-illegal-filename": "API error message that can be used for client side localisation of API errors.", - "api-error-internal-error": "API error message that can be used for client side localisation of API errors.", - "api-error-invalid-file-key": "API error message that can be used for client side localisation of API errors.", - "api-error-missingparam": "API error message that can be used for client side localisation of API errors.", - "api-error-missingresult": "API error message that can be used for client side localisation of API errors.", - "api-error-mustbeloggedin": "API error message that can be used for client side localisation of API errors.", - "api-error-mustbeposted": "API error message that can be used for client side localisation of API errors.", - "api-error-noimageinfo": "API error message that can be used for client side localisation of API errors.", - "api-error-nomodule": "API error message that can be used for client side localisation of API errors.", - "api-error-ok-but-empty": "API error message that can be used for client side localisation of API errors.", - "api-error-overwrite": "API error message that can be used for client side localisation of API errors.", - "api-error-ratelimited": "API error message that can be used for client side localisation of API errors.\n\nCf. {{msg-mw|Actionthrottledtext}}", "api-error-stashfailed": "API error message that can be used for client side localisation of API errors.", "api-error-publishfailed": "API error message that can be used for client side localisation of API errors.", - "api-error-stasherror": "API error message that can be used for client side localisation of API errors.", - "api-error-stashedfilenotfound": "API error message that can be used for client side localisation of API errors.", - "api-error-stashpathinvalid": "API error message that can be used for client side localisation of API errors.", - "api-error-stashfilestorage": "API error message that can be used for client side localisation of API errors.", - "api-error-stashzerolength": "API error message that can be used for client side localisation of API errors.", - "api-error-stashnotloggedin": "API error message that can be used for client side localisation of API errors.", - "api-error-stashwrongowner": "API error message that can be used for client side localisation of API errors.", - "api-error-stashnosuchfilekey": "API error message that can be used for client side localisation of API errors.", - "api-error-timeout": "API error message that can be used for client side localisation of API errors.", - "api-error-unclassified": "API error message that can be used for client side localisation of API errors.", - "api-error-unknown-code": "API error message that can be used for client side localisation of API errors.\n\nParameters:\n* $1 - may contain more error details\n{{Identical|Unknown error}}", - "api-error-unknown-error": "API error message that can be used for client side localisation of API errors.", "api-error-unknown-warning": "API error message that can be used for client side localisation of API errors. Parameters:\n* $1 is an unknown warning.", "api-error-unknownerror": "API error message that can be used for client side localisation of API errors.\n\nParameters:\n* $1 - an unknown error message\n{{Identical|Unknown error}}", - "api-error-uploaddisabled": "API error message that can be used for client side localisation of API errors.", - "api-error-verification-error": "The word \"extension\" refers to the part behind the last dot in a file name, that by convention gives a hint about the kind of data format which a files contents are in.", - "api-error-was-deleted": "API error message that can be used for client side localisation of API errors.", "duration-seconds": "Used as duration. Parameters:\n* $1 - number of seconds\n{{Related|Duration}}\n{{Identical|Second}}", "duration-minutes": "Used as duration. Parameters:\n* $1 - number of minutes\n{{Related|Duration}}\n{{Identical|Minute}}", "duration-hours": "Used as duration. Parameters:\n* $1 - number of hours\n{{Related|Duration}}\n{{Identical|Hour}}", diff --git a/resources/Resources.php b/resources/Resources.php index 7c00feb052..7006a066f5 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -1276,59 +1276,18 @@ return [ 'upload-form-label-infoform-description-tooltip', 'upload-form-label-usage-title', 'upload-form-label-usage-filename', - 'api-error-unknownerror', + 'action-upload', + 'apierror-mustbeloggedin', + 'badaccess-groups', + 'apierror-unknownerror', 'api-error-unknown-warning', - 'api-error-autoblocked', - 'api-error-blocked', - 'api-error-badaccess-groups', - 'api-error-badtoken', - 'api-error-copyuploaddisabled', - 'api-error-duplicate', - 'api-error-duplicate-archive', - 'api-error-empty-file', - 'api-error-emptypage', - 'api-error-fetchfileerror', - 'api-error-fileexists-forbidden', - 'api-error-fileexists-shared-forbidden', - 'api-error-file-too-large', - 'api-error-filename-tooshort', - 'api-error-filetype-banned', - 'api-error-filetype-banned-type', - 'api-error-filetype-missing', - 'api-error-hookaborted', - 'api-error-http', - 'api-error-illegal-filename', - 'api-error-internal-error', - 'api-error-invalid-file-key', - 'api-error-missingparam', - 'api-error-missingresult', - 'api-error-mustbeloggedin', - 'api-error-mustbeposted', - 'api-error-noimageinfo', - 'api-error-nomodule', - 'api-error-ok-but-empty', - 'api-error-overwrite', - 'api-error-stashfailed', - 'api-error-publishfailed', - 'api-error-stasherror', - 'api-error-stashedfilenotfound', - 'api-error-stashpathinvalid', - 'api-error-stashfilestorage', - 'api-error-stashzerolength', - 'api-error-stashnotloggedin', - 'api-error-stashwrongowner', - 'api-error-stashnosuchfilekey', - 'api-error-timeout', - 'api-error-unclassified', - 'api-error-unknown-code', - 'api-error-unknown-error', - 'api-error-uploaddisabled', - 'api-error-verification-error', - 'api-error-was-deleted', 'fileexists', 'filepageexists', + 'file-exists-duplicate', + 'file-deleted-duplicate', 'filename-bad-prefix', 'filename-thumb-name', + 'filewasdeleted', 'badfilename', 'protectedpagetext', ], diff --git a/resources/src/mediawiki/mediawiki.ForeignStructuredUpload.BookletLayout.js b/resources/src/mediawiki/mediawiki.ForeignStructuredUpload.BookletLayout.js index 543ece881d..f2b6f5f9c3 100644 --- a/resources/src/mediawiki/mediawiki.ForeignStructuredUpload.BookletLayout.js +++ b/resources/src/mediawiki/mediawiki.ForeignStructuredUpload.BookletLayout.js @@ -128,7 +128,14 @@ * @return {mw.Upload} */ mw.ForeignStructuredUpload.BookletLayout.prototype.createUpload = function () { - return new mw.ForeignStructuredUpload( this.target ); + return new mw.ForeignStructuredUpload( this.target, { + parameters: { + errorformat: 'html', + errorlang: mw.config.get( 'wgUserLanguage' ), + errorsuselocal: 1, + formatversion: 2 + } + } ); }; /* Form renderers */ diff --git a/resources/src/mediawiki/mediawiki.Upload.BookletLayout.js b/resources/src/mediawiki/mediawiki.Upload.BookletLayout.js index f736036ecf..172cac2379 100644 --- a/resources/src/mediawiki/mediawiki.Upload.BookletLayout.js +++ b/resources/src/mediawiki/mediawiki.Upload.BookletLayout.js @@ -181,9 +181,9 @@ function ( userInfo ) { if ( userInfo.rights.indexOf( 'upload' ) === -1 ) { if ( mw.user.isAnon() ) { - booklet.getPage( 'upload' ).$element.msg( 'api-error-mustbeloggedin' ); + booklet.getPage( 'upload' ).$element.msg( 'apierror-mustbeloggedin', mw.msg( 'action-upload' ) ); } else { - booklet.getPage( 'upload' ).$element.msg( 'api-error-badaccess-groups' ); + booklet.getPage( 'upload' ).$element.msg( 'apierror-permissiondenied', mw.msg( 'action-upload' ) ); } } return $.Deferred().resolve(); @@ -206,7 +206,14 @@ * @return {mw.Upload} Upload model */ mw.Upload.BookletLayout.prototype.createUpload = function () { - return new mw.Upload(); + return new mw.Upload( { + parameters: { + errorformat: 'html', + errorlang: mw.config.get( 'wgUserLanguage' ), + errorsuselocal: 1, + formatversion: 2 + } + } ); }; /* Uploading */ @@ -319,58 +326,23 @@ * @return {jQuery.Promise} A Promise that will be resolved with an OO.ui.Error. */ mw.Upload.BookletLayout.prototype.getErrorMessageForStateDetails = function () { - var message, - state = this.upload.getState(), + var state = this.upload.getState(), stateDetails = this.upload.getStateDetails(), - error = stateDetails.error, - warnings = stateDetails.upload && stateDetails.upload.warnings; + error = stateDetails.errors ? stateDetails.errors[ 0 ] : false, + warnings = stateDetails.upload && stateDetails.upload.warnings, + $ul = $( '