diff options
-rw-r--r-- | nbxmpp/protocol.py | 26 | ||||
-rw-r--r-- | nbxmpp/structs.py | 49 | ||||
-rw-r--r-- | nbxmpp/util.py | 21 |
3 files changed, 79 insertions, 17 deletions
diff --git a/nbxmpp/protocol.py b/nbxmpp/protocol.py index fd66c15..c6a747f 100644 --- a/nbxmpp/protocol.py +++ b/nbxmpp/protocol.py @@ -1084,11 +1084,27 @@ class Protocol(Node): of the error (otherwise) """ errtag = self.getTag('error') - if errtag: - for tag in errtag.getChildren(): - if tag.getName() != 'text': - return tag.getName() - return errtag.getData() + if errtag is None: + return + for tag in errtag.getChildren(): + if tag.getName() != 'text' and tag.getNamespace() == NS_STANZAS: + return tag.getName() + + def getAppError(self): + errtag = self.getTag('error') + if errtag is None: + return + for tag in errtag.getChildren(): + if tag.getName() != 'text' and tag.getNamespace() != NS_STANZAS: + return tag.getName() + + def getAppErrorNamespace(self): + errtag = self.getTag('error') + if errtag is None: + return + for tag in errtag.getChildren(): + if tag.getName() != 'text' and tag.getNamespace() != NS_STANZAS: + return tag.getNamespace() def getErrorMsg(self): """ diff --git a/nbxmpp/structs.py b/nbxmpp/structs.py index acf2bab..f6a22cc 100644 --- a/nbxmpp/structs.py +++ b/nbxmpp/structs.py @@ -309,11 +309,52 @@ class OMEMOBundle(namedtuple('OMEMOBundle', 'spk spk_signature ik otpks')): return random.SystemRandom().choice(self.otpks) -class CommonError(namedtuple('CommonError', 'type message jid')): +class CommonError: + def __init__(self, stanza): + self._error_node = stanza.getTag('error') + self.condition = stanza.getError() + self.app_condition = stanza.getAppError() + self.type = stanza.getErrorType() + self.jid = stanza.getFrom() + self.id = stanza.getID() + self._text = {} + + error = stanza.getTag('error') + if error is not None: + text_elements = error.getTags('text', namespace=NS_STANZAS) + for element in text_elements: + lang = element.getXmlLang() + text = element.getData() + self._text[lang] = text + + def get_text(self, pref_lang=None): + if pref_lang is not None: + text = self._text.get(pref_lang) + if text is not None: + return text + + if self._text: + text = self._text.get('en') + if text is not None: + return text + + text = self._text.get(None) + if text is not None: + return text + return self._text.popitem()[1] + return '' + + def set_text(self, lang, text): + self._text[lang] = text + def __str__(self): - if self.message is not None: - return 'Error from %s %s: %s' % (self.jid, self.type, self.message) - return 'Error from %s: %s' % (self.jid, self.type) + condition = self.condition + if self.app_condition is not None: + condition = '%s (%s)' % (self.condition, self.app_condition) + text = self.get_text('en') or '' + if text: + text = ' - %s' % text + return 'Error from %s: %s%s' % (self.jid, condition, text) class TuneData(namedtuple('TuneData', 'artist length rating source title track uri')): diff --git a/nbxmpp/util.py b/nbxmpp/util.py index c018bf6..6170984 100644 --- a/nbxmpp/util.py +++ b/nbxmpp/util.py @@ -138,14 +138,19 @@ def to_xs_boolean(value): 'Cant convert %s to xs:boolean' % value) -def raise_error(log_method, stanza, type_=None, message=None): - if message is not None: - message = str(message) - if type_ is None: - type_ = stanza.getError() - message = stanza.getErrorMsg() - jid = stanza.getFrom() - error = CommonError(type_, message, jid) +error_classes = {} + +def error_factory(stanza): + app_namespace = stanza.getAppErrorNamespace() + return error_classes.get(app_namespace, CommonError)(stanza) + + +def raise_error(log_method, stanza, condition=None, text=None): + error = error_factory(stanza) + if text is not None: + error.set_text('en', str(text)) + if condition is not None: + error.condition = str(condition) log_method(error) if log_method.__name__ in ('warning', 'error'): log_method(stanza) |