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

View File

@ -64,6 +64,26 @@ class InvalidTorrentError(DelugeError):
class InvalidPathError(DelugeError):
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):
pass

View File

@ -194,8 +194,12 @@ class DelugeRPCProtocol(Protocol):
msg += "\n" + "-" * 80
msg += "\n" + "RPCRequest: " + r.__repr__()
msg += "\n" + "-" * 80
msg += "\n" + request[5] + "\n" + request[2] + ": "
msg += str(exception)
if isinstance(exception, error.WrappedException):
msg += "\n" + exception.type + "\n" + exception.message + ": "
msg += exception.traceback
else:
msg += "\n" + request[5] + "\n" + request[2] + ": "
msg += str(exception)
msg += "\n" + "-" * 80
if not isinstance(exception, error._ClientSideRecreateError):
@ -203,7 +207,7 @@ class DelugeRPCProtocol(Protocol):
log.error(msg)
else:
# The rest just get's logged in debug level, just to log
# what's happending
# what's happening
log.debug(msg)
d.errback(exception)
@ -617,7 +621,7 @@ class Client(object):
self._daemon_proxy.disconnect()
self.stop_classic_mode()
return
if self._daemon_proxy:
return self._daemon_proxy.disconnect()
@ -634,7 +638,7 @@ class Client(object):
"""
self._daemon_proxy = None
self.__started_in_classic = False
def start_daemon(self, port, config):
"""
Starts a daemon process.