diff options
Diffstat (limited to 'lang/python/src/errors.py')
-rw-r--r-- | lang/python/src/errors.py | 109 |
1 files changed, 85 insertions, 24 deletions
diff --git a/lang/python/src/errors.py b/lang/python/src/errors.py index 1ce139e8..c41ac692 100644 --- a/lang/python/src/errors.py +++ b/lang/python/src/errors.py @@ -1,3 +1,4 @@ +# Copyright (C) 2016-2017 g10 Code GmbH # Copyright (C) 2004 Igor Belyi <[email protected]> # Copyright (C) 2002 John Goerzen <[email protected]> # @@ -30,32 +31,89 @@ util.process_constants('GPG_ERR_', globals()) del util class GpgError(Exception): - pass + """A GPG Error -class GPGMEError(GpgError): - def __init__(self, error = None, message = None): + This is the base of all errors thrown by this library. + + If the error originated from GPGME, then additional information + can be found by looking at 'code' for the error code, and 'source' + for the errors origin. Suitable constants for comparison are + defined in this module. 'code_str' and 'source_str' are + human-readable versions of the former two properties. + + If 'context' is not None, then it contains a human-readable hint + as to where the error originated from. + + If 'results' is not None, it is a tuple containing results of the + operation that failed. The tuples elements are the results of the + function that raised the error. Some operations return results + even though they signal an error. Of course this information must + be taken with a grain of salt. But often, this information is + useful for diagnostic uses or to give the user feedback. Since + the normal control flow is disrupted by the exception, the callee + can no longer return results, hence we attach them to the + exception objects. + + """ + def __init__(self, error=None, context=None, results=None): self.error = error - self.message = message + self.context = context + self.results = results + + @property + def code(self): + if self.error == None: + return None + return gpgme.gpgme_err_code(self.error) + + @property + def code_str(self): + if self.error == None: + return None + return gpgme.gpgme_strerror(self.error) + + @property + def source(self): + if self.error == None: + return None + return gpgme.gpgme_err_source(self.error) + + @property + def source_str(self): + if self.error == None: + return None + return gpgme.gpgme_strsource(self.error) + + def __str__(self): + msgs = [] + if self.context != None: + msgs.append(self.context) + if self.error != None: + msgs.append(self.source_str) + msgs.append(self.code_str) + return ': '.join(msgs) + +class GPGMEError(GpgError): + '''Generic error + + This is a generic error that wraps the underlying libraries native + error type. It is thrown when the low-level API is invoked and + returns an error. This is the error that was used in PyME. + ''' @classmethod def fromSyserror(cls): return cls(gpgme.gpgme_err_code_from_syserror()) - + @property + def message(self): + return self.context def getstring(self): - message = "%s: %s" % (gpgme.gpgme_strsource(self.error), - gpgme.gpgme_strerror(self.error)) - if self.message != None: - message = "%s: %s" % (self.message, message) - return message - + return str(self) def getcode(self): - return gpgme.gpgme_err_code(self.error) - + return self.code def getsource(self): - return gpgme.gpgme_err_source(self.error) + return self.source - def __str__(self): - return self.getstring() def errorcheck(retval, extradata = None): if retval: @@ -81,7 +139,8 @@ class EncryptionError(GpgError): pass class InvalidRecipients(EncryptionError): - def __init__(self, recipients): + def __init__(self, recipients, **kwargs): + EncryptionError.__init__(self, **kwargs) self.recipients = recipients def __str__(self): return ", ".join("{}: {}".format(r.fpr, @@ -92,7 +151,8 @@ class DeryptionError(GpgError): pass class UnsupportedAlgorithm(DeryptionError): - def __init__(self, algorithm): + def __init__(self, algorithm, **kwargs): + DeryptionError.__init__(self, **kwargs) self.algorithm = algorithm def __str__(self): return self.algorithm @@ -101,7 +161,8 @@ class SigningError(GpgError): pass class InvalidSigners(SigningError): - def __init__(self, signers): + def __init__(self, signers, **kwargs): + SigningError.__init__(self, **kwargs) self.signers = signers def __str__(self): return ", ".join("{}: {}".format(s.fpr, @@ -109,11 +170,11 @@ class InvalidSigners(SigningError): for s in self.signers) class VerificationError(GpgError): - pass + def __init__(self, result, **kwargs): + GpgError.__init__(self, **kwargs) + self.result = result class BadSignatures(VerificationError): - def __init__(self, result): - self.result = result def __str__(self): return ", ".join("{}: {}".format(s.fpr, gpgme.gpgme_strerror(s.status)) @@ -121,8 +182,8 @@ class BadSignatures(VerificationError): if s.status != NO_ERROR) class MissingSignatures(VerificationError): - def __init__(self, result, missing): - self.result = result + def __init__(self, result, missing, **kwargs): + VerificationError.__init__(self, result, **kwargs) self.missing = missing def __str__(self): return ", ".join(k.subkeys[0].fpr for k in self.missing) |