Error handling and logging system

RPC Error codes and pre-defined exceptions

django-modern-rpc provide exceptions to cover common errors when requests are processed.

Error handling is fully described in both XML & JSON-RPC standards. Each common error have an associated faultCode and the response format is described, so errors can be handled correctly on the client side.

In django-modern-rpc, all errors are reported using a set of pre-defined exceptions. Thus, in JSON and XML-RPC handlers, when an exception is caught, the correct error response is returned to the view and transmitted to the client.

This simplify error management, and allow developers to simply return errors to clients from inside a RPC Method. The error codes values are defined in:

Pre-defined exceptions uses the following error codes:

RPC_PARSE_ERROR = -32700
RPC_INVALID_REQUEST = -32600
RPC_METHOD_NOT_FOUND = -32601
RPC_INVALID_PARAMS = -32602
RPC_INTERNAL_ERROR = -32603

# Used as minimal value for any custom error returned by the server
RPC_CUSTOM_ERROR_BASE = -32099
# Used as maximal value for any custom error returned by the server
RPC_CUSTOM_ERROR_MAX = -32000
exception modernrpc.exceptions.AuthenticationFailed(method_name)[source]

Raised when authentication system forbade execution of a RPC Method

exception modernrpc.exceptions.RPCException(code, message, data=None)[source]

This is the base class of all RPC exception. Custom exceptions raised by your RPC methods should inherits from RPCException.

exception modernrpc.exceptions.RPCInternalError(message, data=None)[source]

Raised by handlers if any standard exception is raised during the execution of the RPC method.

exception modernrpc.exceptions.RPCInvalidParams(message, data=None)[source]

Raised by handlers if the RPC method’s params does not match the parameters in RPC request

exception modernrpc.exceptions.RPCInvalidRequest(message, data=None)[source]

Raised by handlers if incoming JSON or XML data is not a valid JSON-RPC or XML-RPC data.

exception modernrpc.exceptions.RPCParseError(message, data=None)[source]

Raised by handlers if the request can’t be read as valid JSOn or XML data.

exception modernrpc.exceptions.RPCUnknownMethod(name, data=None)[source]

Raised by handlers the RPC method called is not defined for the current entry point and protocol.

Customize error handling

If you want to define customized exceptions for your application, you can create RPCException sub-classes and set, for each custom exception, a faultCode to RPC_CUSTOM_ERROR_BASE + N with N a unique number.

Here is an example:

class MyException1(RPCException):
    def __init__(self, message):
        super(MyException1, self).__init__(RPC_CUSTOM_ERROR_BASE + 1, message)

class MyException2(RPCException):
    def __init__(self, message):
        super(MyException2, self).__init__(RPC_CUSTOM_ERROR_BASE + 2, message)

Anyway, any exception raised during the RPC method execution will generate a RPCInternalError with an error message constructed from the underlying error. As a result, the RPC client will have a correct message describing what went wrong.

Logging

Django-modern-rpc use Python logging system to report some information, warning and errors. If you need to troubleshoot issues, you can enable logging capabilities.

You only have to configure settings.LOGGING to handle log messages from modernrpc.core and modernrpc.views. Here is a basic example of such a configuration:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        # Your formatters configuration...
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        # your other loggers configuration
        'modernrpc': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': True,
        },
    }
}

All information about logging configuration can be found in official Django docs.

New in version 0.7: By default, logs from modernrpc.* modules are discarded silently. This behavior prevent the common Python 2 error message “No handlers could be found for logger XXX”.