Error reporting from the API urgently needs work. The dieUsage() function originally designed to signal usage errors to bot owners has become the default way of reporting errors from the API, but is not suitable for showing detailed localized messages on the UI.
After some discussion, Anomie and I came up with the following plan (as far as I recall):
- The API needs to return message keys and parameters for errors and warnings, for client side localization. The
messages are returned as <message> elements in the <error> resp <warning> section.
- Error codes are no longer needed, message keys can be used as machine readable identifiers
- For backwards compatibility, the English translation of the message(s) (and, for errors, and error code) should be returned to the called. This can skip messages from the database.
- The old behavior should be retained as the default for the <error> and <warning> sections. The new behavior can be triggered using appropriate parameters (perhaps apimessages=true or some such)
- For convenience, the API can be instructed to include a translated HTML version of the messages in the output, in the user's language or some language given as a parameter (e.g. triggered using apimessage=html & apilang=fr), considering customization using message pages. The text is returned in a <html> element in the <error> resp <warning> section.
To allow the new functionality, the ApiBase class needs to support new functions for reporting errors and warnings:
- dieMessage( Message $msg ): report the given message as an error and abort. If old style output is requested, use the message key as the error code and use the English translation of the message as the error info.
- warnMessage( Message $msg ): report the given message as a warning and continue. If old style output is requested, use the English translation of the message in the <warning> section.
- handleStatus( Status $status ): use the messages from a Status object
- if the status is fatal, report any error messages in the Status object as errors and abort.
- if the status is not fatal but has errors or warnings, report all messages in the Status object as warnings and continue.
- else, just carry on.
For backwards compatibility, the old reporting functions should be retained (but deprecated). They should implement a sensible default when used with the new style output:
- dieUsage( $info, $code ): if the new style of error reporting is requested, this will generate a generic message (perhaps api-usage-error) with $info and $code as the two message parameters.
- dieUsageMsg( $error ): if the new style of error reporting is requested, report the message given as an error. Otherwise, keep using the old hard coded message-key-to-error-code mapping in ApiMain::$messageMap.
Example of the new behavior:
<error> <message key="something-went-wrong"> <param>Foo</param> <param>23</param> </message> <html lang="de"> <p>Mit "Foo" ist etwas schiefgegangen (ID: 23).</p> </html> </error> <warning> <message key="some-stuff"/> <message key="other-stuff"> <param>X</param> </message> <html lang="de"> <ul> <li>So Zeug!</li> <li>Noch mehr Zeug: X!</li> </ul> </html> </warning>
Example of old style output for dieError( wfMessage( "nasty-error", "X" ) ):
<error code="nasty-error" info="Nasty Error with X"/>
Example of new style output for dieUsage( "Nasty Error", "silly-code" ):
<error> <message key="api-usage-error"> <param>Nasty Error</param> <param>silly-code</param> </message> </error>
See Also: T47277: Improve localizable error messages for API calls