HTTPretty icon indicating copy to clipboard operation
HTTPretty copied to clipboard

Exceptions raised in callbacks are not passed back

Open andy-maier opened this issue 7 years ago • 2 comments

We are using httpretty (in the pywbem project) and a few of our test cases should simulate connection issues by raising exceptions. We raise them in httpretty callbacks, e.g.:

def socket_104(request, uri, headers):
    raise socket.error(104, "Connection reset by peer.")

The test case looks like this, simplifying the actual code to the minimum:

@httpretty.activate
def runtestcase(testcase):
    httpretty.httpretty.allow_net_connect = False
    params = {
        "body": socket_104
    }
    httpretty.register_uri(method='POST', uri='/cimom', **params)
    try:
        result = op_call(**op_args)  # sends HTTP/HTTPS request and reads response
        raised_exception = None
    except Exception as exc:
        raised_exception = exc
        result = None
    # . . . assert raised_exception

The problem is that httpretty creates a thread in its implementation of the socket.makefile() method, and executes the callbacks in that thread, but does not pass any exceptions raised in that thread back to the main thread.

The issue is that this causes an exception traceback to be printed in the thread, and the exception information is lost and cannot be processed in the main thread.

This could be solved by using the following ExcThread class in fakesock.socket.makefile() in httpretty/core.py instead of using threading.Thread:

class ExcThread(threading.Thread):

    def run(self):
        self.exc = None
        try:
            threading.Thread.run(self)
        except Exception:
            import sys
            self.exc = sys.exc_info()

    def join(self, *args, **kwargs):
        threading.Thread.join(self, *args, **kwargs)
        if self.exc:
             six.reraise(*self.exc)

In fakesock.socket.makefile():

 def makefile(self, mode='r', bufsize=-1):
     . . .
     if self._entry:
-        t = threading.Thread(
+        t = ExcThread(
             target=self._entry.fill_filekind, args=(self.fd,)
         )

andy-maier avatar Apr 17 '18 00:04 andy-maier

Good solution 👍, alternatively I think it might be good for some to monkey patch the old httpretty implementation of makefile.

Longer term, I think that reverting https://github.com/gabrielfalcao/HTTPretty/pull/202 is the best course of action to avoid issues like this.

murrayrush avatar Sep 04 '18 14:09 murrayrush

Any updates on this issue? This is still a problem.

holmanb avatar Feb 02 '22 14:02 holmanb