d8d9e8df16
If a stanza handler raised an exception, the exception was processed and replied by the modified stanza, not a stanza with the original content. A copy is now made before handler processing, and if an exception occurs it is the copy that processes the exception using the original content.
183 lines
5.5 KiB
Python
183 lines
5.5 KiB
Python
import sys
|
|
import sleekxmpp
|
|
from sleekxmpp.xmlstream.matcher import MatchXPath
|
|
from sleekxmpp.xmlstream.handler import Callback
|
|
from sleekxmpp.exceptions import XMPPError
|
|
from sleekxmpp.test import *
|
|
|
|
|
|
class TestStreamExceptions(SleekTest):
|
|
"""
|
|
Test handling roster updates.
|
|
"""
|
|
|
|
def tearDown(self):
|
|
sys.excepthook = sys.__excepthook__
|
|
self.stream_close()
|
|
|
|
def testExceptionReply(self):
|
|
"""Test that raising an exception replies with the original stanza."""
|
|
|
|
def message(msg):
|
|
msg.reply()
|
|
msg['body'] = 'Body changed'
|
|
raise XMPPError(clear=False)
|
|
|
|
|
|
sys.excepthook = lambda *args, **kwargs: None
|
|
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>
|
|
""")
|
|
|
|
def testXMPPErrorException(self):
|
|
"""Test raising an XMPPError exception."""
|
|
|
|
def message(msg):
|
|
raise XMPPError(condition='feature-not-implemented',
|
|
text="We don't do things that way here.",
|
|
etype='cancel',
|
|
extension='foo',
|
|
extension_ns='foo:error',
|
|
extension_args={'test': 'true'})
|
|
|
|
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">
|
|
<error type="cancel" code="501">
|
|
<feature-not-implemented
|
|
xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
|
|
<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
|
|
We don't do things that way here.
|
|
</text>
|
|
<foo xmlns="foo:error" test="true" />
|
|
</error>
|
|
</message>
|
|
""", use_values=False)
|
|
|
|
def testIqErrorException(self):
|
|
"""Test using error exceptions with Iq stanzas."""
|
|
|
|
def handle_iq(iq):
|
|
raise XMPPError(condition='feature-not-implemented',
|
|
text="We don't do things that way here.",
|
|
etype='cancel',
|
|
clear=False)
|
|
|
|
self.stream_start()
|
|
self.xmpp.register_handler(
|
|
Callback(
|
|
'Test Iq',
|
|
MatchXPath('{%s}iq/{test}query' % self.xmpp.default_ns),
|
|
handle_iq))
|
|
|
|
self.recv("""
|
|
<iq type="get" id="0">
|
|
<query xmlns="test" />
|
|
</iq>
|
|
""")
|
|
|
|
self.send("""
|
|
<iq type="error" id="0">
|
|
<query xmlns="test" />
|
|
<error type="cancel" code="501">
|
|
<feature-not-implemented
|
|
xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
|
|
<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
|
|
We don't do things that way here.
|
|
</text>
|
|
</error>
|
|
</iq>
|
|
""", use_values=False)
|
|
|
|
def testThreadedXMPPErrorException(self):
|
|
"""Test raising an XMPPError exception in a threaded handler."""
|
|
|
|
def message(msg):
|
|
raise XMPPError(condition='feature-not-implemented',
|
|
text="We don't do things that way here.",
|
|
etype='cancel')
|
|
|
|
self.stream_start()
|
|
self.xmpp.add_event_handler('message', message,
|
|
threaded=True)
|
|
|
|
self.recv("""
|
|
<message>
|
|
<body>This is going to cause an error.</body>
|
|
</message>
|
|
""")
|
|
|
|
self.send("""
|
|
<message type="error">
|
|
<error type="cancel" code="501">
|
|
<feature-not-implemented
|
|
xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
|
|
<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
|
|
We don't do things that way here.
|
|
</text>
|
|
</error>
|
|
</message>
|
|
""")
|
|
|
|
def testUnknownException(self):
|
|
"""Test raising an generic exception in a threaded handler."""
|
|
|
|
raised_errors = []
|
|
|
|
def message(msg):
|
|
raise ValueError("Did something wrong")
|
|
|
|
def catch_error(*args, **kwargs):
|
|
raised_errors.append(True)
|
|
|
|
sys.excepthook = catch_error
|
|
|
|
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">
|
|
<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], "Exception was not raised: %s" % raised_errors)
|
|
|
|
|
|
|
|
suite = unittest.TestLoader().loadTestsFromTestCase(TestStreamExceptions)
|