2 This file is part of notmuch.
4 Notmuch is free software: you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation, either version 3 of the License, or (at your
7 option) any later version.
9 Notmuch is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License
15 along with notmuch. If not, see <http://www.gnu.org/licenses/>.
17 Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
20 from ctypes import c_char_p, c_int
22 from .globals import (
29 """Enum with a string representation of a notmuch_status_t value."""
30 _status2str = nmlib.notmuch_status_to_string
31 _status2str.restype = c_char_p
32 _status2str.argtypes = [c_int]
34 def __init__(self, statuslist):
35 """It is initialized with a list of strings that are available as
36 Status().string1 - Status().stringn attributes.
38 super(Status, self).__init__(statuslist)
41 def status2str(self, status):
42 """Get a (unicode) string representation of a notmuch_status_t value."""
43 # define strings for custom error messages
44 if status == STATUS.NOT_INITIALIZED:
45 return "Operation on uninitialized object impossible."
46 return unicode(Status._status2str(status))
48 STATUS = Status(['SUCCESS',
54 'DUPLICATE_MESSAGE_ID',
57 'UNBALANCED_FREEZE_THAW',
60 """STATUS is a class, whose attributes provide constants that serve as return
61 indicators for notmuch functions. Currently the following ones are defined. For
62 possible return values and specific meaning for each method, see the method
71 * DUPLICATE_MESSAGE_ID
74 * UNBALANCED_FREEZE_THAW
78 Invoke the class method `notmuch.STATUS.status2str` with a status value as
79 argument to receive a human readable string"""
80 STATUS.__name__ = 'STATUS'
83 class NotmuchError(Exception, Python3StringMixIn):
84 """Is initiated with a (notmuch.STATUS[, message=None]). It will not
85 return an instance of the class NotmuchError, but a derived instance
86 of a more specific Error Message, e.g. OutOfMemoryError. Each status
87 but SUCCESS has a corresponding subclassed Exception."""
90 def get_exc_subclass(cls, status):
91 """Returns a fine grained Exception() type,
92 detailing the error status"""
94 STATUS.OUT_OF_MEMORY: OutOfMemoryError,
95 STATUS.READ_ONLY_DATABASE: ReadOnlyDatabaseError,
96 STATUS.XAPIAN_EXCEPTION: XapianError,
97 STATUS.FILE_ERROR: FileError,
98 STATUS.FILE_NOT_EMAIL: FileNotEmailError,
99 STATUS.DUPLICATE_MESSAGE_ID: DuplicateMessageIdError,
100 STATUS.NULL_POINTER: NullPointerError,
101 STATUS.TAG_TOO_LONG: TagTooLongError,
102 STATUS.UNBALANCED_FREEZE_THAW: UnbalancedFreezeThawError,
103 STATUS.UNBALANCED_ATOMIC: UnbalancedAtomicError,
104 STATUS.NOT_INITIALIZED: NotInitializedError,
106 assert 0 < status <= len(subclasses)
107 return subclasses[status]
109 def __new__(cls, *args, **kwargs):
110 """Return a correct subclass of NotmuchError if needed
112 We return a NotmuchError instance if status is None (or 0) and a
113 subclass that inherits from NotmuchError depending on the
114 'status' parameter otherwise."""
115 # get 'status'. Passed in as arg or kwarg?
116 status = args[0] if len(args) else kwargs.get('status', None)
117 # no 'status' or cls is subclass already, return 'cls' instance
118 if not status or cls != NotmuchError:
119 return super(NotmuchError, cls).__new__(cls)
120 subclass = cls.get_exc_subclass(status) # which class to use?
121 return subclass.__new__(subclass, *args, **kwargs)
123 def __init__(self, status=None, message=None):
125 self.message = message
127 def __unicode__(self):
128 if self.message is not None:
130 elif self.status is not None:
131 return STATUS.status2str(self.status)
133 return 'Unknown error'
136 # List of Subclassed exceptions that correspond to STATUS values and are
137 # subclasses of NotmuchError.
138 class OutOfMemoryError(NotmuchError):
139 status = STATUS.OUT_OF_MEMORY
142 class ReadOnlyDatabaseError(NotmuchError):
143 status = STATUS.READ_ONLY_DATABASE
146 class XapianError(NotmuchError):
147 status = STATUS.XAPIAN_EXCEPTION
150 class FileError(NotmuchError):
151 status = STATUS.FILE_ERROR
154 class FileNotEmailError(NotmuchError):
155 status = STATUS.FILE_NOT_EMAIL
158 class DuplicateMessageIdError(NotmuchError):
159 status = STATUS.DUPLICATE_MESSAGE_ID
162 class NullPointerError(NotmuchError):
163 status = STATUS.NULL_POINTER
166 class TagTooLongError(NotmuchError):
167 status = STATUS.TAG_TOO_LONG
170 class UnbalancedFreezeThawError(NotmuchError):
171 status = STATUS.UNBALANCED_FREEZE_THAW
174 class UnbalancedAtomicError(NotmuchError):
175 status = STATUS.UNBALANCED_ATOMIC
178 class NotInitializedError(NotmuchError):
179 """Derived from NotmuchError, this occurs if the underlying data
180 structure (e.g. database is not initialized (yet) or an iterator has
181 been exhausted. You can test for NotmuchError with .status =
182 STATUS.NOT_INITIALIZED"""
183 status = STATUS.NOT_INITIALIZED