Wrap non deluge exceptions so that they can also be sent to the client.

This commit is contained in:
Pedro Algarvio 2011-06-05 22:44:01 +01:00
commit ddc0957e3e
3 changed files with 39 additions and 9 deletions

View file

@ -57,7 +57,7 @@ import deluge.component as component
import deluge.configmanager import deluge.configmanager
from deluge.core.authmanager import (AUTH_LEVEL_NONE, AUTH_LEVEL_DEFAULT, from deluge.core.authmanager import (AUTH_LEVEL_NONE, AUTH_LEVEL_DEFAULT,
AUTH_LEVEL_ADMIN) AUTH_LEVEL_ADMIN)
from deluge.error import (DelugeError, NotAuthorizedError, from deluge.error import (DelugeError, NotAuthorizedError, WrappedException,
_ClientSideRecreateError, IncompatibleClient) _ClientSideRecreateError, IncompatibleClient)
RPC_RESPONSE = 1 RPC_RESPONSE = 1
@ -246,6 +246,7 @@ class DelugeRPCProtocol(Protocol):
Sends an error response with the contents of the exception that was raised. Sends an error response with the contents of the exception that was raised.
""" """
exceptionType, exceptionValue, exceptionTraceback = sys.exc_info() exceptionType, exceptionValue, exceptionTraceback = sys.exc_info()
formated_tb = "".join(traceback.format_tb(exceptionTraceback))
try: try:
self.sendData(( self.sendData((
RPC_ERROR, RPC_ERROR,
@ -253,13 +254,18 @@ class DelugeRPCProtocol(Protocol):
exceptionType.__name__, exceptionType.__name__,
exceptionValue._args, exceptionValue._args,
exceptionValue._kwargs, exceptionValue._kwargs,
"".join(traceback.format_tb(exceptionTraceback)) formated_tb
)) ))
except Exception, err: except Exception, err:
# This most likely not a deluge exception, let's wrap it
log.error("An exception occurred while sending RPC_ERROR to " log.error("An exception occurred while sending RPC_ERROR to "
"client. Error to send(exception goes next): %s", "client. Wrapping it and resending. Error to "
"".join(traceback.format_tb(exceptionTraceback))) "send(causing exception goes next):\n%s", formated_tb)
log.exception(err) log.exception(err)
try:
raise WrappedException(str(exceptionValue), exceptionType.__name__, formated_tb)
except:
sendError()
if method == "daemon.info": if method == "daemon.info":
# This is a special case and used in the initial connection process # This is a special case and used in the initial connection process

View file

@ -64,6 +64,26 @@ class InvalidTorrentError(DelugeError):
class InvalidPathError(DelugeError): class InvalidPathError(DelugeError):
pass pass
class WrappedException(DelugeError):
def _get_traceback(self):
return self._traceback
def _set_traceback(self, traceback):
self._traceback = traceback
traceback = property(_get_traceback, _set_traceback)
del _get_traceback, _set_traceback
def _get_type(self):
return self._type
def _set_type(self, type):
self._type = type
type = property(_get_type, _set_type)
del _get_type, _set_type
def __init__(self, message, exception_type, traceback):
self.message = message
self.type = exception_type
self.traceback = traceback
class _ClientSideRecreateError(DelugeError): class _ClientSideRecreateError(DelugeError):
pass pass

View file

@ -194,6 +194,10 @@ class DelugeRPCProtocol(Protocol):
msg += "\n" + "-" * 80 msg += "\n" + "-" * 80
msg += "\n" + "RPCRequest: " + r.__repr__() msg += "\n" + "RPCRequest: " + r.__repr__()
msg += "\n" + "-" * 80 msg += "\n" + "-" * 80
if isinstance(exception, error.WrappedException):
msg += "\n" + exception.type + "\n" + exception.message + ": "
msg += exception.traceback
else:
msg += "\n" + request[5] + "\n" + request[2] + ": " msg += "\n" + request[5] + "\n" + request[2] + ": "
msg += str(exception) msg += str(exception)
msg += "\n" + "-" * 80 msg += "\n" + "-" * 80
@ -203,7 +207,7 @@ class DelugeRPCProtocol(Protocol):
log.error(msg) log.error(msg)
else: else:
# The rest just get's logged in debug level, just to log # The rest just get's logged in debug level, just to log
# what's happending # what's happening
log.debug(msg) log.debug(msg)
d.errback(exception) d.errback(exception)