1 from notmuch2 import _capi as capi
4 class NotmuchError(Exception):
5 """Base exception for errors originating from the notmuch library.
7 Usually this will have two attributes:
9 :status: This is a numeric status code corresponding to the error
10 code in the notmuch library. This is normally fairly
11 meaningless, it can also often be ``None``. This exists mostly
12 to easily create new errors from notmuch status codes and
13 should not normally be used by users.
15 :message: A user-facing message for the error. This can
16 occasionally also be ``None``. Usually you'll want to call
17 ``str()`` on the error object instead to get a sensible
22 def exc_type(cls, status):
23 """Return correct exception type for notmuch status."""
25 capi.lib.NOTMUCH_STATUS_OUT_OF_MEMORY:
27 capi.lib.NOTMUCH_STATUS_READ_ONLY_DATABASE:
28 ReadOnlyDatabaseError,
29 capi.lib.NOTMUCH_STATUS_XAPIAN_EXCEPTION:
31 capi.lib.NOTMUCH_STATUS_FILE_ERROR:
33 capi.lib.NOTMUCH_STATUS_FILE_NOT_EMAIL:
35 capi.lib.NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID:
36 DuplicateMessageIdError,
37 capi.lib.NOTMUCH_STATUS_NULL_POINTER:
39 capi.lib.NOTMUCH_STATUS_TAG_TOO_LONG:
41 capi.lib.NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW:
42 UnbalancedFreezeThawError,
43 capi.lib.NOTMUCH_STATUS_UNBALANCED_ATOMIC:
44 UnbalancedAtomicError,
45 capi.lib.NOTMUCH_STATUS_UNSUPPORTED_OPERATION:
46 UnsupportedOperationError,
47 capi.lib.NOTMUCH_STATUS_UPGRADE_REQUIRED:
49 capi.lib.NOTMUCH_STATUS_PATH_ERROR:
51 capi.lib.NOTMUCH_STATUS_ILLEGAL_ARGUMENT:
53 capi.lib.NOTMUCH_STATUS_NO_CONFIG:
55 capi.lib.NOTMUCH_STATUS_NO_DATABASE:
57 capi.lib.NOTMUCH_STATUS_DATABASE_EXISTS:
59 capi.lib.NOTMUCH_STATUS_BAD_QUERY_SYNTAX:
64 def __new__(cls, *args, **kwargs):
65 """Return the correct subclass based on status."""
66 # This is simplistic, but the actual __init__ will fail if the
67 # signature is wrong anyway.
71 status = kwargs.get('status', None)
72 if status and cls == NotmuchError:
73 exc = cls.exc_type(status)
74 return exc.__new__(exc, *args, **kwargs)
76 return super().__new__(cls)
78 def __init__(self, status=None, message=None):
80 self.message = message
86 char_str = capi.lib.notmuch_status_to_string(self.status)
87 return capi.ffi.string(char_str).decode(errors='replace')
89 return 'Unknown error'
92 class OutOfMemoryError(NotmuchError): pass
93 class ReadOnlyDatabaseError(NotmuchError): pass
94 class XapianError(NotmuchError): pass
95 class FileError(NotmuchError): pass
96 class FileNotEmailError(NotmuchError): pass
97 class DuplicateMessageIdError(NotmuchError): pass
98 class NullPointerError(NotmuchError): pass
99 class TagTooLongError(NotmuchError): pass
100 class UnbalancedFreezeThawError(NotmuchError): pass
101 class UnbalancedAtomicError(NotmuchError): pass
102 class UnsupportedOperationError(NotmuchError): pass
103 class UpgradeRequiredError(NotmuchError): pass
104 class PathError(NotmuchError): pass
105 class IllegalArgumentError(NotmuchError): pass
106 class NoConfigError(NotmuchError): pass
107 class NoDatabaseError(NotmuchError): pass
108 class DatabaseExistsError(NotmuchError): pass
109 class QuerySyntaxError(NotmuchError): pass
111 class ObjectDestroyedError(NotmuchError):
112 """The object has already been destroyed and it's memory freed.
114 This occurs when :meth:`destroy` has been called on the object but
115 you still happen to have access to the object. This should not
116 normally occur since you should never call :meth:`destroy` by
124 return 'Memory already freed'