def callFromThread(self, f, *args, **kw): assert callable(f), "%s is not callable" % f with NullContext(): # This NullContext is mainly for an edge case when running # TwistedIOLoop on top of a TornadoReactor. # TwistedIOLoop.add_callback uses reactor.callFromThread and # should not pick up additional StackContexts along the way. self._io_loop.add_callback(f, *args, **kw)
def test_exception_logging(self): """Uncaught exceptions get logged by the IOLoop.""" # Use a NullContext to keep the exception from being caught by # AsyncTestCase. with NullContext(): self.io_loop.add_callback(lambda: 1 / 0) self.io_loop.add_callback(self.stop) with ExpectLog(app_log, "Exception in callback"): self.wait()
def make_wrapped_function(): """Wraps a function in three stack contexts, and returns the function along with the deactivation functions. """ # Remove the test's stack context to make sure we can cover # the case where the last context is deactivated. with NullContext(): partial = functools.partial with StackContext(partial(self.context, 'c0')) as c0: with StackContext(partial(self.context, 'c1')) as c1: with StackContext(partial(self.context, 'c2')) as c2: return (wrap(check_contexts), [c0, c1, c2])
def test_exception_logging_native_coro(self): """The IOLoop examines exceptions from awaitables and logs them.""" namespace = exec_test( globals(), locals(), """ async def callback(): self.io_loop.add_callback(self.stop) 1 / 0 """) with NullContext(): self.io_loop.add_callback(namespace["callback"]) with ExpectLog(app_log, "Exception in callback"): self.wait()
def test_exception_logging_future(self): """The IOLoop examines exceptions from Futures and logs them.""" with NullContext(): @gen.coroutine def callback(): self.io_loop.add_callback(self.stop) 1 / 0 self.io_loop.add_callback(callback) with ExpectLog(app_log, "Exception in callback"): self.wait()
def test_handle_callback_exception(self): # IOLoop.handle_callback_exception can be overridden to catch # exceptions in callbacks. def handle_callback_exception(callback): self.assertIs(sys.exc_info()[0], ZeroDivisionError) self.stop() self.io_loop.handle_callback_exception = handle_callback_exception with NullContext(): # remove the test StackContext that would see this uncaught # exception as a test failure. self.io_loop.add_callback(lambda: 1 / 0) self.wait()
def addWriter(self, writer): if writer in self._writers: return fd = writer.fileno() self._writers[writer] = fd if fd in self._fds: (reader, _) = self._fds[fd] self._fds[fd] = (reader, writer) if reader: # We already registered this fd for read events, # update it for write events as well. self._io_loop.update_handler(fd, IOLoop.READ | IOLoop.WRITE) else: with NullContext(): self._fds[fd] = (None, writer) self._io_loop.add_handler(fd, self._invoke_callback, IOLoop.WRITE)
def test_read_callback_error(self): # Test that IOStream sets its exc_info when a read callback throws server, client = self.make_iostream_pair() try: server.set_close_callback(self.stop) with ExpectLog( app_log, "(Uncaught exception|Exception in callback)" ): # Clear ExceptionStackContext so IOStream catches error with NullContext(): server.read_bytes(1, callback=lambda data: 1 / 0) client.write(b"1") self.wait() self.assertTrue(isinstance(server.error, ZeroDivisionError)) finally: server.close() client.close()
def addReader(self, reader): if reader in self._readers: # Don't add the reader if it's already there return fd = reader.fileno() self._readers[reader] = fd if fd in self._fds: (_, writer) = self._fds[fd] self._fds[fd] = (reader, writer) if writer: # We already registered this fd for write events, # update it for read events as well. self._io_loop.update_handler(fd, IOLoop.READ | IOLoop.WRITE) else: with NullContext(): self._fds[fd] = (reader, None) self._io_loop.add_handler(fd, self._invoke_callback, IOLoop.READ)
def test_final_callback_stack_context(self): # The final callback should be run outside of the httpclient's # stack_context. We want to ensure that there is not stack_context # between the user's callback and the IOLoop, so monkey-patch # IOLoop.handle_callback_exception and disable the test harness's # context with a NullContext. # Note that this does not apply to secondary callbacks (header # and streaming_callback), as errors there must be seen as errors # by the http client so it can clean up the connection. exc_info = [] def handle_callback_exception(callback): exc_info.append(sys.exc_info()) self.stop() self.io_loop.handle_callback_exception = handle_callback_exception with NullContext(): self.http_client.fetch(self.get_url('/hello'), lambda response: 1 / 0) self.wait() self.assertEqual(exc_info[0][0], ZeroDivisionError)
def f1(): with NullContext(): wrapped = wrap(f2) with StackContext(functools.partial(self.context, 'c2')): wrapped()