Errors handling in web services

Jump to: navigation, search

Exceptions

Format

Exceptions are caught by the server that generate its own error format. All exceptions contain a translated message + debuginfo. The php format should be :

//this is an example. The exception parameters depend how they are implemented in the exception class.
throw new exception_class_name('errorcode', 'component', $a, '', 'This is an untranslated debug info.' );

REST-XML

<?xml version="1.0" encoding="UTF-8" ?>
<EXCEPTION class="invalid_parameter_exception">
<ERRORCODE>invalidparameter</ERRORCODE>
<MESSAGE>Invalid parameter value detected</MESSAGE>
<DEBUGINFO>Username already exists: testusername1</DEBUGINFO>
</EXCEPTION>

REST-JSON

{
"exception":"invalid_parameter_exception",
"errorcode":"invalidparameter",
"message":"Invalid parameter value detected",
"debuginfo":"Username already exists: testusername1"
}

XML-RPC

Array
(
    [faultCode] => 29039061 //this is a errorcode specific to xmlrpc. As we could not return a string as faultCode (e.g. 'invalidparameter'), 
                             we transformed the usual errorcode into a long. Note in some very rare case, 
                             two exceptions "could" have the same faultCode (we don't know any of these rare cases 
                             but better to alert you if something goes weird)
    [faultString] => Invalid parameter value detected | DEBUG INFO: Username already exists: testusername1 | ERRORCODE: invalidparameter
                      //here you can parse the message to get the errorcode in the last '|'. 
)

SOAP

SoapFault Object ( .... 
[faultstring] => Invalid parameter value detected | ERRORCODE: invalidparameter //exception message (errorcode also included at the end)
[faultcode] => Receiver //soap faultcode
[faultactor] => invalidparameter // errorcode
[detail] => Username already exists: testusername1 //debuginfo
)

How to handle exception on the client side

  • error code: the string key of the exception message. The key should be specific enough to be able to implement specific client behaviour against it.
  • Message: translated error message. It's possible for the client to display this message to the user.
  • Debuginfo: not translated detailled error message (dynamic => this message can change following the error). Help the client dev to debug.

When to send an exception on the server side

Everything that is going to be skipped or not done is an exception.

  • DB WRITE functions must rollback when an exception is raised. We usually throw back the exception to the server.
  • Example: the user does not have appropriate access rights to call the function.

Warning messages

Warning messages can be included in the return value of external functions. The structure can be found into lib/externallib.php.

Format

The warning format is different following the protocol. It can be JSON or XML. REST/SOAP/XMLRPC all got different XML format. However they all implement the following structure:

/**
 * Standard Moodle web service warnings
 *
 * @package    core_webservice
 * @copyright  2012 Jerome Mouneyrac
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @since Moodle 2.3
 */
class external_warnings extends external_multiple_structure {
 
    /**
     * Constructor
     *
     * @since Moodle 2.3
     */
    public function __construct($itemdesc = 'item', $itemiddesc = 'item id',
        $warningcodedesc = 'the warning code can be used by the client app to implement specific behaviour') {
 
        parent::__construct(
            new external_single_structure(
                array(
                    'item' => new external_value(PARAM_TEXT, $itemdesc, VALUE_OPTIONAL),
                    'itemid' => new external_value(PARAM_INT, $itemiddesc, VALUE_OPTIONAL),
                    'warningcode' => new external_value(PARAM_ALPHANUM, $warningcodedesc),
                    'message' => new external_value(PARAM_TEXT,
                            'untranslated english message to explain the warning')
                ), 'warning'),
            'list of warnings', VALUE_OPTIONAL);
    }
}

How to handle warning on the client side

Warnings are in the return value so nothing is different from how you handle other returned info. You should be able to implement some code logic against the returned warnings.

When to send a warning on the server side

The web services must match 100% of Moodle behaviors. When Moodle core stops the execution, then the external function throws an exception. When Moodle core returns some warnings instead of stopping the execution (like multiple backup lib function) then the web service function also return warnings.

Bulk function that has no matching core code

Quite often the web service functions will be a bulk version of an existing core lib function. Because the bulk core lib function doesn't exist, it is the decision of the external function developer to return warnings or exceptions. For example if the data are inter-dependant it will make sens to stop the execution. If the same capability is required for each operation, then it also make sens to stop the execution. For errors specific to one operation, then a warnings will be more suitable.

Warnings examples

  • the user lastname is trimmed
  • the language for this user was not specified so $CFG->defaultlang has been used.