From 0774b5cebaadd5587724d59e64ddbe30ce11f6a5 Mon Sep 17 00:00:00 2001
From: Joshua Harlow <harlowja@gmail.com>
Date: Fri, 4 Mar 2016 11:52:34 -0800
Subject: [PATCH] Always delete exc_info tuple, even if reply fails

Avoid any possible references to exc_info tuple by ensuring
we delete it in a finally block, so that even if replying or
logging fails somehow the prior exception is always deleted
correctly.

Change-Id: Id0e5099b9b38b1803bb4514f7cf3deae760d5ac3
---
 oslo_messaging/rpc/dispatcher.py | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/oslo_messaging/rpc/dispatcher.py b/oslo_messaging/rpc/dispatcher.py
index b3a299517..cecef2224 100644
--- a/oslo_messaging/rpc/dispatcher.py
+++ b/oslo_messaging/rpc/dispatcher.py
@@ -145,13 +145,15 @@ class RPCDispatcher(dispatcher.DispatcherBase):
             # by another exception raise by a log handler during
             # LOG.exception(). So keep a copy and delete it later.
             exc_info = sys.exc_info()
-            LOG.error(_LE('Exception during message handling: %s'), e,
-                      exc_info=exc_info)
-            incoming.reply(failure=exc_info)
-            # NOTE(dhellmann): Remove circular object reference
-            # between the current stack frame and the traceback in
-            # exc_info.
-            del exc_info
+            try:
+                LOG.error(_LE('Exception during message handling: %s'), e,
+                          exc_info=exc_info)
+                incoming.reply(failure=exc_info)
+            finally:
+                # NOTE(dhellmann): Remove circular object reference
+                # between the current stack frame and the traceback in
+                # exc_info.
+                del exc_info
 
     def _dispatch(self, ctxt, message):
         """Dispatch an RPC message to the appropriate endpoint method.