Jajcus / pyxmpp

XMPP implementation for Python

Home Page:http://pyxmpp.jajcus.net/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

In certain cases pyxmpp eats exceptions

Jajcus opened this issue · comments

xmlextra.endElement() eats exceptions, instead of letting them propagate.

While it's bad style to let exceptions get away from callbacks, it may happen and then errors don't get reported. In my case an unexpected UnicodeEncodeError from pyxmpp code itself wasn't caught in my code, wreaked some havoc and vanished without a trace. Not a pleasant thing to debug.

Relevant part of a stack from my case to illustrate the issue:

{{{
File "/home/karol/programowanie/pyxmpp/pyxmpp/xmlextra.py", line 214, in endElement
self._handler.stanza(self._doc, node1)
File "/home/karol/programowanie/pyxmpp/pyxmpp/streambase.py", line 401, in stanza
self._process_node(node)
File "/home/karol/programowanie/pyxmpp/pyxmpp/stream.py", line 107, in _process_node
StreamBase._process_node(self,xmlnode)
File "/home/karol/programowanie/pyxmpp/pyxmpp/streambase.py", line 710, in _process_node
self.process_stanza(stanza)
File "/home/karol/programowanie/pyxmpp/pyxmpp/stanzaprocessor.py", line 274, in process_stanza
if self.process_message(stanza):
File "/home/karol/programowanie/pyxmpp/pyxmpp/stanzaprocessor.py", line 209, in process_message
return self.__try_handlers(self._message_handlers,"normal",stanza)
File "/home/karol/programowanie/pyxmpp/pyxmpp/stanzaprocessor.py", line 185, in __try_handlers
response = handler(stanza)
File "/home/karol/programowanie/soc/tmp/jabberbot/xmppbot.py", line 372, in handle_message
response = self.handle_internal_command(sender, command)
File "/home/karol/programowanie/soc/tmp/jabberbot/xmppbot.py", line 402, in handle_internal_command
self.send_search_form(sender)
File "/home/karol/programowanie/soc/tmp/jabberbot/xmppbot.py", line 319, in send_search_form
message.add_content(form)
File "/home/karol/programowanie/pyxmpp/pyxmpp/stanza.py", line 303, in add_content
content.as_xml(parent = self.xmlnode, doc = common_doc)
File "/home/karol/programowanie/pyxmpp/pyxmpp/objects.py", line 91, in as_xml
self.complete_xml_element(xmlnode, doc1)
File "/home/karol/programowanie/pyxmpp/pyxmpp/jabber/dataforms.py", line 632, in complete_xml_element
xmlnode.newTextChild(ns, "title", self.title)
File "/usr/lib64/python2.3/site-packages/libxml2.py", line 3325, in newTextChild
ret = libxml2mod.xmlNewTextChild(self._o, ns__o, name, content)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u015b' in position 2: ordinal not in range(128)
}}}

i have rewritten the xmlextra.endElement() function so that it does not eat error propagation. the described behaviour resulted from the extensive use of 'finally' statements in error trapping.

please take this WITH CAUTION as i have not fully tested it, however it does seem to solve my issues.

anyone trying this out please let the community and jajcus if this can be officially set in the svn rep.

the rewritten function can be seen here below, and i have attached the complete file for your convenience.

{{{

    def endElement(self, tag):
        ""
        self._current+="</%s>" % (tag,)
        self._level -= 1
        if self._level > 1:
            return
        if self._level==1:
            xml=self._head+self._current+self._tail
            doc=libxml2.parseDoc(xml)
            try:
                node = doc.getRootElement().children
            except:
                doc.freeDoc()
                return
            try:
                node1 = node.docCopyNode(self._doc, 1)
            except:
                del node
                doc.freeDoc()
                return
            try:
                self._root.addChild(node1)
            except:
                node1.unlinkNode()
                node1.freeNode()
                del node1
                del node
                doc.freeDoc()
            try:
                self._handler.stanza(self._doc, node1)
            except:
                node1.unlinkNode()
                node1.freeNode()
                del node1
                del node
                doc.freeDoc()
                raise
            del node1
            del node
            doc.freeDoc()
        else:
            xml=self._head+self._tail
            doc=libxml2.parseDoc(xml)
            try:
                self._handler.stream_end(self._doc)
                self._doc.freeDoc()
                self._doc = None
                self._root = None
            finally:
                doc.freeDoc()

}}}

--roberto ostinelli

forgot a return statement

{{{
def endElement(self, tag):
""
self._current+="</%s>" % (tag,)
self._level -= 1
if self._level > 1:
return
if self._level==1:
xml=self._head+self._current+self._tail
doc=libxml2.parseDoc(xml)
try:
node = doc.getRootElement().children
except:
doc.freeDoc()
return
try:
node1 = node.docCopyNode(self._doc, 1)
except:
del node
doc.freeDoc()
return
try:
self._root.addChild(node1)
except:
node1.unlinkNode()
node1.freeNode()
del node1
del node
doc.freeDoc()
return
try:
self._handler.stanza(self._doc, node1)
except:
node1.unlinkNode()
node1.freeNode()
del node1
del node
doc.freeDoc()
raise
del node1
del node
doc.freeDoc()
else:
xml=self._head+self._tail
doc=libxml2.parseDoc(xml)
try:
self._handler.stream_end(self._doc)
self._doc.freeDoc()
self._doc = None
self._root = None
finally:
doc.freeDoc()
}}}

--roberto ostinelli

I have tested with xmlextra.3.py, when the SASLAuthenticationFailed exception raised, it still can't work right. the exception was eation by xmlpaser. see the follow message:

File "C:\Python25\Lib\site-packages\pyxmpp\xmlextra.py", line 229, in endElement
self._handler.stanza(self._doc, node1)
File "C:\Python25\Lib\site-packages\pyxmpp\streambase.py", line 402, in stanza
self._process_node(node)
File "C:\Python25\Lib\site-packages\pyxmpp\stream.py", line 105, in _process_node
if self._process_node_sasl(xmlnode):
File "C:\Python25\lib\site-packages\pyxmpp\streamsasl.py", line 102, in _process_node_sasl
self._process_sasl_node(xmlnode)
File "C:\Python25\lib\site-packages\pyxmpp\streamsasl.py", line 121, in _process_sasl_node
ret=self._process_sasl_failure(xmlnode)
File "C:\Python25\lib\site-packages\pyxmpp\streamsasl.py", line 322, in _process_sasl_failure
raise SASLAuthenticationFailed,"SASL authentication failed"
pyxmpp.exceptions.SASLAuthenticationFailed: SASL authentication failed

--anonymous

SASLAuthenticationFailed exception can be handled right in pyxmpp 1.0.1.
I have tested it in win32 platform.

--anonymous

Assuming (assumption based on the last comment) it is fixed.

--jajcus

The same problem still happens (Ubuntu lucid, PyXMPP version 1.1.1) - this exception doesn't seem to be propagated upwards.
Also tested with the fixes mentioned previously in this ticket - to no avail.

Traceback (most recent call last):
File "../pyxmpp/xmlextra.py", line 225, in endElement
self._handler.stanza(self._doc, node1)
File "../pyxmpp/streambase.py", line 401, in stanza
self._process_node(node)
File "../pyxmpp/stream.py", line 105, in _process_node
if self._process_node_sasl(xmlnode):
File "../pyxmpp/streamsasl.py", line 102, in _process_node_sasl
self._process_sasl_node(xmlnode)
File "../pyxmpp/streamsasl.py", line 121, in _process_sasl_node
ret=self._process_sasl_failure(xmlnode)
File "../pyxmpp/streamsasl.py", line 322, in _process_sasl_failure
raise SASLAuthenticationFailed,"SASL authentication failed"
pyxmpp.exceptions.SASLAuthenticationFailed: SASL authentication failed

--adamk

I have the same problem with the SASLAuthenticationFailed issue. Any clues to help narrow the scope of the investigation into finding a fix are much appreciated.