summaryrefslogtreecommitdiff
path: root/sleekxmpp/stanza/rootstanza.py
diff options
context:
space:
mode:
Diffstat (limited to 'sleekxmpp/stanza/rootstanza.py')
-rw-r--r--sleekxmpp/stanza/rootstanza.py87
1 files changed, 87 insertions, 0 deletions
diff --git a/sleekxmpp/stanza/rootstanza.py b/sleekxmpp/stanza/rootstanza.py
new file mode 100644
index 00000000..2ac47d8b
--- /dev/null
+++ b/sleekxmpp/stanza/rootstanza.py
@@ -0,0 +1,87 @@
+"""
+ SleekXMPP: The Sleek XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of SleekXMPP.
+
+ See the file LICENSE for copying permission.
+"""
+
+import logging
+import traceback
+import sys
+
+from sleekxmpp.exceptions import XMPPError, IqError, IqTimeout
+from sleekxmpp.stanza import Error
+from sleekxmpp.xmlstream import ET, StanzaBase, register_stanza_plugin
+
+
+log = logging.getLogger(__name__)
+
+
+class RootStanza(StanzaBase):
+
+ """
+ A top-level XMPP stanza in an XMLStream.
+
+ The RootStanza class provides a more XMPP specific exception
+ handler than provided by the generic StanzaBase class.
+
+ Methods:
+ exception -- Overrides StanzaBase.exception
+ """
+
+ def exception(self, e):
+ """
+ Create and send an error reply.
+
+ Typically called when an event handler raises an exception.
+ The error's type and text content are based on the exception
+ object's type and content.
+
+ Overrides StanzaBase.exception.
+
+ Arguments:
+ e -- Exception object
+ """
+ if isinstance(e, IqError):
+ # We received an Iq error reply, but it wasn't caught
+ # locally. Using the condition/text from that error
+ # response could leak too much information, so we'll
+ # only use a generic error here.
+ self.reply()
+ self['error']['condition'] = 'undefined-condition'
+ self['error']['text'] = 'External error'
+ self['error']['type'] = 'cancel'
+ log.warning('You should catch IqError exceptions')
+ self.send()
+ elif isinstance(e, IqTimeout):
+ self.reply()
+ self['error']['condition'] = 'remote-server-timeout'
+ self['error']['type'] = 'wait'
+ log.warning('You should catch IqTimeout exceptions')
+ self.send()
+ elif isinstance(e, XMPPError):
+ # We raised this deliberately
+ self.reply(clear=e.clear)
+ self['error']['condition'] = e.condition
+ self['error']['text'] = e.text
+ self['error']['type'] = e.etype
+ if e.extension is not None:
+ # Extended error tag
+ extxml = ET.Element("{%s}%s" % (e.extension_ns, e.extension),
+ e.extension_args)
+ self['error'].append(extxml)
+ self.send()
+ else:
+ # We probably didn't raise this on purpose, so send an error stanza
+ self.reply()
+ self['error']['condition'] = 'undefined-condition'
+ self['error']['text'] = "SleekXMPP got into trouble."
+ self['error']['type'] = 'cancel'
+ self.send()
+ # log the error
+ log.exception('Error handling {%s}%s stanza' , self.namespace, self.name)
+ # Finally raise the exception to a global exception handler
+ self.stream.exception(e)
+
+register_stanza_plugin(RootStanza, Error)