Merge branch 'develop' into stream_features

This commit is contained in:
Lance Stout 2011-07-01 15:19:37 -07:00
commit 04def6d925
6 changed files with 112 additions and 39 deletions

View file

@ -64,8 +64,7 @@ class RootStanza(StanzaBase):
# log the error # log the error
log.exception('Error handling {%s}%s stanza' % log.exception('Error handling {%s}%s stanza' %
(self.namespace, self.name)) (self.namespace, self.name))
# Finally raise the exception, so it can be handled (or not) # Finally raise the exception to a global exception handler
# at a higher level by using sys.excepthook. self.stream.exception(e)
raise e
register_stanza_plugin(RootStanza, Error) register_stanza_plugin(RootStanza, Error)

View file

@ -764,7 +764,6 @@ class XMLStream(object):
Event handlers and the send queue will be threaded Event handlers and the send queue will be threaded
regardless of this parameter's value. regardless of this parameter's value.
""" """
self._thread_excepthook()
self.scheduler.process(threaded=True) self.scheduler.process(threaded=True)
def start_thread(name, target): def start_thread(name, target):
@ -1052,30 +1051,16 @@ class XMLStream(object):
self.event_queue.put(('quit', None, None)) self.event_queue.put(('quit', None, None))
return return
def _thread_excepthook(self): def exception(self, exception):
""" """
If a threaded event handler raises an exception, there is no way to Process an unknown exception.
catch it except with an excepthook. Currently, each thread has its own
excepthook, but ideally we could use the main sys.excepthook.
Modifies threading.Thread to use sys.excepthook when an exception Meant to be overridden.
is not caught.
Arguments:
exception -- An unhandled exception object.
""" """
init_old = threading.Thread.__init__ pass
def init(self, *args, **kwargs):
init_old(self, *args, **kwargs)
run_old = self.run
def run_with_except_hook(*args, **kw):
try:
run_old(*args, **kw)
except (KeyboardInterrupt, SystemExit):
raise
except:
sys.excepthook(*sys.exc_info())
self.run = run_with_except_hook
threading.Thread.__init__ = init
# To comply with PEP8, method names now use underscores. # To comply with PEP8, method names now use underscores.

View file

@ -12,7 +12,6 @@ class TestStreamExceptions(SleekTest):
""" """
def tearDown(self): def tearDown(self):
sys.excepthook = sys.__excepthook__
self.stream_close() self.stream_close()
def testExceptionReply(self): def testExceptionReply(self):
@ -23,8 +22,6 @@ class TestStreamExceptions(SleekTest):
msg['body'] = 'Body changed' msg['body'] = 'Body changed'
raise XMPPError(clear=False) raise XMPPError(clear=False)
sys.excepthook = lambda *args, **kwargs: None
self.stream_start() self.stream_start()
self.xmpp.add_event_handler('message', message) self.xmpp.add_event_handler('message', message)
@ -44,6 +41,49 @@ class TestStreamExceptions(SleekTest):
</message> </message>
""") """)
def testExceptionContinueWorking(self):
"""Test that Sleek continues to respond after an XMPPError is raised."""
def message(msg):
msg.reply()
msg['body'] = 'Body changed'
raise XMPPError(clear=False)
self.stream_start()
self.xmpp.add_event_handler('message', message)
self.recv("""
<message>
<body>This is going to cause an error.</body>
</message>
""")
self.send("""
<message type="error">
<body>This is going to cause an error.</body>
<error type="cancel" code="500">
<undefined-condition
xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
</error>
</message>
""")
self.recv("""
<message>
<body>This is going to cause an error.</body>
</message>
""")
self.send("""
<message type="error">
<body>This is going to cause an error.</body>
<error type="cancel" code="500">
<undefined-condition
xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
</error>
</message>
""")
def testXMPPErrorException(self): def testXMPPErrorException(self):
"""Test raising an XMPPError exception.""" """Test raising an XMPPError exception."""
@ -153,9 +193,8 @@ class TestStreamExceptions(SleekTest):
def catch_error(*args, **kwargs): def catch_error(*args, **kwargs):
raised_errors.append(True) raised_errors.append(True)
sys.excepthook = catch_error
self.stream_start() self.stream_start()
self.xmpp.exception = catch_error
self.xmpp.add_event_handler('message', message) self.xmpp.add_event_handler('message', message)
self.recv(""" self.recv("""
@ -178,6 +217,58 @@ class TestStreamExceptions(SleekTest):
self.assertEqual(raised_errors, [True], "Exception was not raised: %s" % raised_errors) self.assertEqual(raised_errors, [True], "Exception was not raised: %s" % raised_errors)
def testUnknownException(self):
"""Test Sleek continues to respond after an unknown exception."""
raised_errors = []
def message(msg):
raise ValueError("Did something wrong")
def catch_error(*args, **kwargs):
raised_errors.append(True)
self.stream_start()
self.xmpp.exception = catch_error
self.xmpp.add_event_handler('message', message)
self.recv("""
<message>
<body>This is going to cause an error.</body>
</message>
""")
self.send("""
<message type="error">
<error type="cancel" code="500">
<undefined-condition
xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
SleekXMPP got into trouble.
</text>
</error>
</message>
""")
self.recv("""
<message>
<body>This is going to cause an error.</body>
</message>
""")
self.send("""
<message type="error">
<error type="cancel" code="500">
<undefined-condition
xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
SleekXMPP got into trouble.
</text>
</error>
</message>
""")
self.assertEqual(raised_errors, [True, True], "Exceptions were not raised: %s" % raised_errors)
suite = unittest.TestLoader().loadTestsFromTestCase(TestStreamExceptions) suite = unittest.TestLoader().loadTestsFromTestCase(TestStreamExceptions)

View file

@ -12,7 +12,6 @@ class TestStreamDisco(SleekTest):
""" """
def tearDown(self): def tearDown(self):
sys.excepthook = sys.__excepthook__
self.stream_close() self.stream_close()
def testInfoEmptyDefaultNode(self): def testInfoEmptyDefaultNode(self):
@ -531,11 +530,6 @@ class TestStreamDisco(SleekTest):
raised_exceptions = [] raised_exceptions = []
def catch_exception(*args, **kwargs):
raised_exceptions.append(True)
sys.excepthook = catch_exception
self.stream_start(mode='client', self.stream_start(mode='client',
plugins=['xep_0030', 'xep_0059']) plugins=['xep_0030', 'xep_0059'])
@ -544,8 +538,14 @@ class TestStreamDisco(SleekTest):
iterator=True) iterator=True)
results.amount = 10 results.amount = 10
def run_test():
try:
results.next()
except StopIteration:
raised_exceptions.append(True)
t = threading.Thread(name="get_items_iterator", t = threading.Thread(name="get_items_iterator",
target=results.next) target=run_test)
t.start() t.start()
self.send(""" self.send("""

View file

@ -13,7 +13,6 @@ class TestStreamExtendedDisco(SleekTest):
""" """
def tearDown(self): def tearDown(self):
sys.excepthook = sys.__excepthook__
self.stream_close() self.stream_close()
def testUsingExtendedInfo(self): def testUsingExtendedInfo(self):

View file

@ -13,7 +13,6 @@ class TestStreamDirectInvite(SleekTest):
""" """
def tearDown(self): def tearDown(self):
sys.excepthook = sys.__excepthook__
self.stream_close() self.stream_close()
def testReceiveInvite(self): def testReceiveInvite(self):