Add some smart magic, so that when we invoke a
NotmuchError(STATUSVALUE), a nicely derived subclass is created, e.g. a
OutOfMemoryError. This way users can easily distinguish between error
types, while still catching NotmuchError.
I have tested this, and hope it works for others too.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
To make the exception handling more effective in code using the
python bindings it is necessary to differentiate between the
different kind of failures.
Add an exception class for each status code and add a decode
classmethod to the NotmuchError class that acts as a factory.
Import the new classes in __init__.py so they can be easily
imported by anyone.
Patch modifed by Sebastian Spaeth.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de>
1) Fix added .gitignore from commit dc8a1745 to work on the docs folder
2) Improve in-code developer documentation to produce better
sphinx-generated documentation. No code changes.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Make note that find_message_by_name currently crashes the python process
if the Database is READ-ONLY. This should be fixed in the underlying
libnotmuch.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
There are various locations where exceptions are constructed but
not raised. This patch adds the necessary raise statements.
Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de>
Raising Exception is considered bad since the only way to catch
it is to do 'except Exception'. Raising a TypeError is more
appropriate.
Since the format parameter has already been validated, checking
it again is not necessary. Simplify this conditional.
Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de>
Rename the function to clarify its effect and remove all the comments
accompanying each call to the function.
Modified by Sebastian Spaeth to apply cleanly again and remove some
blank lines.
Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de>
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Rename the function to clarify its effect and remove all the comments
accompanying each call to the function.
Modified slightly by Sebastian Spaeth to catch all new instances and
remove some blank lines too.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de>
Passing None to STATUS.status2str raises an ArgumentError. Add a
check for this case and provide a generic message.
Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de>
Providing exception objects with meaningful attribute names
is much nicer than using e.args[].
Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de>
The line 'notmuch' in the toplevel .gitignore file is to broad
and matches bindings/python/notmuch making it cumbersome to
git-add files within that directory.
Refine the toplevel file to only match the generated notmuch
executable and add a more specialized .gitignore file to the
python directory.
Signed-off-by: Justus Winter <4winter@informatik.uni-hamburg.de>
* Add UNBALANCED_ATOMIC status code
Catch up with the notmuch status codes, and add the UNBALANCED_ATOMIC
one.
* Add the begin_atomic and end_atomic calls to libnotmuch
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
The setup is useless if gdb is not present, so it doesn't hurt to skip
it. The diff here is huge, but the commit is really just moving most
of the script inside the initial if, and adding an else block to print
a warning.
As long as we have no version information in the json output, this
seems like the only possible way of ensuring that the emacs client
code understands the output from the command line tool notmuch.
State up front that these functions may add a filename to an existing
message or remove only a filename (and not the message), respectively.
Previously, this key information was buried in return value
documentation or in "notes", which made it seem secondary to these
functions' semantics.
This addresses atomicity of tag synchronization, the last atomicity
problems in notmuch new. Each message add or remove is wrapped in its
own atomic section, so interrupting notmuch new doesn't lose progress.
Because flag synchronization is stateless, it can be performed at any
time as long as it's guaranteed to be performed after any change to a
message's filename list. Take advantage of this to synchronize tags
immediately after a filename is added or removed.
This does not yet make adding or removing a message atomic, but it is
a big step toward atomicity because it reduces the window where the
database tags are inconsistent from nearly the entire notmuch-new to
just around when the message is added or removed.
Previously, file name removal was implemented identically in two
places. Now it's captured in one function.
This is important because file name removal is about to get slightly
more complicated with eager tag synchronization and correct removal
atomicity.
Previously, pointers to these variables were passed around
individually. This was okay when only one function needed them, but
we're about to need them in a few more places.
Adding a message may involve changes to multiple database documents,
and thus needs to be done in a transaction. This makes add_message
(and, I think, the whole library) atomicity-safe: library callers only
needs to use atomic sections if they needs atomicity across multiple
library calls.
notmuch_database_find_message_by_filename is mostly stolen from
notmuch_database_remove_message, so this patch also vastly simplfies
the latter using the former.
This API is also useful in its own right and will be used in a later
patch for eager maildir flag synchronization.
According to the common Ruby function naming convention, potentially
dangerous functions or functions which operate on the object itself are
suffixed with an exclamation mark. Both of these are true for object
destroying functions.
The following modules are affected:
- Notmuch::Directory
- Notmuch::FileNames
- Notmuch::Query
- Notmuch::Threads
- Notmuch::Thread
- Notmuch::Messages
- Notmuch::Message
- Notmuch::Tags
Previously, notmuch_database_remove_message would remove the message
file name, sync the change to the message document, re-find the
message document, and then delete it if there were no more file names.
An interruption after sync'ing would result in a file-name-less,
permanently un-removable zombie message that would produce errors and
odd results in searches. We could wrap this in an atomic section, but
it's much simpler to eliminate the round-about approach and just
delete the message document instead of sync'ing it if we removed the
last filename.
notmuch_database_t now keeps a nesting count and we only start a
transaction or commit for the outermost atomic section.
Introduces a new error, NOTMUCH_STATUS_UNBALANCED_ATOMIC.
Previously, if notmuch new were interrupted between updating the
directory mtime and handling removals from that directory, a
subsequent notmuch new would not handle those removals until something
else changed in that directory. This defers recording the updated
mtime until after removals are handled to eliminate this problem.
If we use unicode objects, libnotmuch would not cope with null bytes in
the byte array, so we need to make sure they are nicely formatted as
utf-8.
Introduce a helper function _str which does this throughout the code.
Patch slightly modified by Sebastian Spaeth.
Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
Previously, message removals were always performed, even after a
SIGINT. As a result, when a message was moved from one folder to
another, a SIGINT between processing the directory the message was
removed from and processing the directory it was added to would result
in notmuch removing that message from the database.
This tests notmuch new's ability to recover from arbitrary stopping
failures. It interrupts notmuch new after every database commit and,
on every resulting database snapshot, re-runs notmuch new to
completion and checks that the final database state is invariant.
Previously, this function would synchronize the folder list even if
removing the file name failed. Now it returns immediately if removing
the file name fails.