From: Leandro Lucarella Date: Fri, 28 Sep 2007 17:11:14 +0000 (-0300) Subject: Improve error handling. X-Git-Url: https://git.llucax.com/software/pymin.git/commitdiff_plain/83738d4fffe1910d9d75849657086d2e4e921a15 Improve error handling. Now all errors that should be reported back to the pymin client should inherit from dispatcher.HandlerError. Any other error is reported to the client as an internal server error and it's printed in the daemon standard output for debugging purposes. A new line is now appended to errors reported to the client for better consistency with OK responses. --- diff --git a/dispatcher.py b/dispatcher.py index 0284da5..b78db93 100644 --- a/dispatcher.py +++ b/dispatcher.py @@ -18,16 +18,17 @@ class Error(RuntimeError): command - is the command that raised the exception, expressed as a list of paths (or subcommands). """ + pass - def __init__(self, command): - r"""Initialize the Error object. +class HandlerError(Error): + r""" + HandlerError(command) -> HandlerError instance :: Base handlers exception. - See Error class documentation for more info. - """ - self.command = command + All exceptions raised by the handlers should inherit from this one, so + dispatching errors could be separated from real programming errors (bugs). + """ + pass - def __str__(self): - return 'Command not found: "%s"' % ' '.join(self.command) class CommandNotFoundError(Error): r""" @@ -36,7 +37,16 @@ class CommandNotFoundError(Error): This exception is raised when the command received can't be dispatched because there is no handlers to process it. """ - pass + + def __init__(self, command): + r"""Initialize the Error object. + + See Error class documentation for more info. + """ + self.command = command + + def __str__(self): + return 'Command not found: "%s"' % ' '.join(self.command) def handler(f): f._dispatcher_handler = True diff --git a/pymindaemon.py b/pymindaemon.py index c3fdda6..b7e56e4 100644 --- a/pymindaemon.py +++ b/pymindaemon.py @@ -65,8 +65,13 @@ class PyminDaemon(eventloop.EventLoop): if result is not None: result = serializer.serialize(result) response = u'OK ' + except dispatcher.Error, e: + result = unicode(e) + u'\n' + response = u'ERROR ' except Exception, e: - result = unicode(e) + import traceback + result = u'Internal server error' + traceback.print_exc() # TODO logging! response = u'ERROR ' if result is None: response += u'0' diff --git a/services/dhcp/__init__.py b/services/dhcp/__init__.py index 5734c2f..b728162 100644 --- a/services/dhcp/__init__.py +++ b/services/dhcp/__init__.py @@ -8,11 +8,17 @@ try: except ImportError: import pickle -import seqtools try: - from dispatcher import handler + from seqtools import Sequence except ImportError: - def handler(f): return f # NOP for testing + # NOP for testing + class Sequence: pass +try: + from dispatcher import handler, HandlerError +except ImportError: + # NOP for testing + class HandlerError(RuntimeError): pass + def handler(f): return f __ALL__ = ('DhcpHandler',) @@ -24,7 +30,7 @@ config_filename = 'dhcpd.conf' template_dir = path.join(path.dirname(__file__), 'templates') -class Error(RuntimeError): +class Error(HandlerError): r""" Error(command) -> Error instance :: Base DhcpHandler exception class. @@ -99,7 +105,7 @@ class ParameterNotFoundError(ParameterError): self.message = 'Parameter not found: "%s"' % paramname -class Host(seqtools.Sequence): +class Host(Sequence): r"""Host(name, ip, mac) -> Host instance :: Class representing a host. name - Host name, should be a fully qualified name, but no checks are done.