diff --git a/radicale/__init__.py b/radicale/__init__.py index 0bc8d1d..1a73686 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -28,6 +28,7 @@ should have been included in this package. import base64 import contextlib +import io import itertools import os import posixpath @@ -130,9 +131,29 @@ class ThreadedHTTPSServer(socketserver.ThreadingMixIn, HTTPSServer): class RequestHandler(wsgiref.simple_server.WSGIRequestHandler): """HTTP requests handler.""" + + # These class attributes must be set before creating instance + logger = None + + def __init__(self, *args, **kwargs): + # Store exception for logging + self.error_stream = io.StringIO() + super().__init__(*args, **kwargs) + + def get_stderr(self): + return self.error_stream + def log_message(self, *args, **kwargs): """Disable inner logging management.""" + def handle(self): + super().handle() + # Log exception + error = self.error_stream.getvalue().strip("\n") + if error: + self.logger.error("An exception occurred during request:\n" + + error) + class Application: """WSGI application managing collections.""" diff --git a/radicale/__main__.py b/radicale/__main__.py index c76acca..4236607 100644 --- a/radicale/__main__.py +++ b/radicale/__main__.py @@ -104,7 +104,11 @@ def run(): if not configuration_found: logger.warning("Configuration file '%s' not found" % options.config) - serve(configuration, logger) + try: + serve(configuration, logger) + except Exception: + logger.exception("An exception occurred during server startup:") + exit(1) def serve(configuration, logger): @@ -175,6 +179,7 @@ def serve(configuration, logger): server_class.max_connections = configuration.getint( "server", "max_connections") + RequestHandler.logger = logger if not configuration.getboolean("server", "dns_lookup"): RequestHandler.address_string = lambda self: self.client_address[0]