summary refs log tree commit diff
path: root/synapse
diff options
context:
space:
mode:
authorAmber Brown <hawkowl@atleastfornow.net>2018-08-21 03:47:52 +1000
committerGitHub <noreply@github.com>2018-08-21 03:47:52 +1000
commit23d7e63a4abbdc19694099902c03b6b7c5144df4 (patch)
treee4c65afdc782c62f8993a4b7343b5e7437a15d45 /synapse
parentchangelog (diff)
parentchangelog (diff)
downloadsynapse-23d7e63a4abbdc19694099902c03b6b7c5144df4.tar.xz
Merge pull request #3723 from matrix-org/rav/fix_logcontext_disaster
Fix exceptions when a connection is closed before we read the headers
Diffstat (limited to 'synapse')
-rw-r--r--synapse/http/site.py8
-rw-r--r--synapse/util/logcontext.py12
2 files changed, 17 insertions, 3 deletions
diff --git a/synapse/http/site.py b/synapse/http/site.py
index ad2a98468e..88ed3714f9 100644
--- a/synapse/http/site.py
+++ b/synapse/http/site.py
@@ -182,7 +182,7 @@ class SynapseRequest(Request):
         # the client disconnects.
         with PreserveLoggingContext(self.logcontext):
             logger.warn(
-                "Error processing request: %s %s", reason.type, reason.value,
+                "Error processing request %r: %s %s", self, reason.type, reason.value,
             )
 
             if not self._is_processing:
@@ -219,6 +219,12 @@ class SynapseRequest(Request):
         """Log the completion of this request and update the metrics
         """
 
+        if self.logcontext is None:
+            # this can happen if the connection closed before we read the
+            # headers (so render was never called). In that case we'll already
+            # have logged a warning, so just bail out.
+            return
+
         usage = self.logcontext.get_resource_usage()
 
         if self._processing_finished_time is None:
diff --git a/synapse/util/logcontext.py b/synapse/util/logcontext.py
index 07e83fadda..a0c2d37610 100644
--- a/synapse/util/logcontext.py
+++ b/synapse/util/logcontext.py
@@ -385,7 +385,13 @@ class LoggingContextFilter(logging.Filter):
         context = LoggingContext.current_context()
         for key, value in self.defaults.items():
             setattr(record, key, value)
-        context.copy_to(record)
+
+        # context should never be None, but if it somehow ends up being, then
+        # we end up in a death spiral of infinite loops, so let's check, for
+        # robustness' sake.
+        if context is not None:
+            context.copy_to(record)
+
         return True
 
 
@@ -396,7 +402,9 @@ class PreserveLoggingContext(object):
 
     __slots__ = ["current_context", "new_context", "has_parent"]
 
-    def __init__(self, new_context=LoggingContext.sentinel):
+    def __init__(self, new_context=None):
+        if new_context is None:
+            new_context = LoggingContext.sentinel
         self.new_context = new_context
 
     def __enter__(self):