pazz / alot

Terminal-based Mail User Agent
GNU General Public License v3.0
696 stars 164 forks source link

notmuch2: `msg.header('From')` fails #1548

Closed pazz closed 3 years ago

pazz commented 3 years ago

It seems that msg.header('From') fails, possibly on a malformed email.

Software Versions

To Reproduce Not entirely sure, for me one a refine command failed on one (not all) querystring.

Error Log

ERROR:ui:Traceback (most recent call last):
  File "/home/pazz/projects/alot/alot/ui.py", line 723, in apply_command
    cmd.apply(self)
  File "/home/pazz/projects/alot/alot/commands/search.py", line 79, in apply
    sbuffer.rebuild()
  File "/home/pazz/projects/alot/alot/buffers/search.py", line 83, in rebuild
    self.focus_thread(selected_thread)
  File "/home/pazz/projects/alot/alot/buffers/search.py", line 131, in focus_thread
    self.consume_pipe_until(lambda w:
  File "/home/pazz/projects/alot/alot/buffers/search.py", line 109, in consume_pipe_until
    or predicate(self.threadlist._get_next_item()):
  File "/home/pazz/projects/alot/alot/walker.py", line 85, in _get_next_item
    next_widget = self.containerclass(next_obj, **self.kwargs)
  File "/home/pazz/projects/alot/alot/widgets/search.py", line 26, in __init__
    self.rebuild()
  File "/home/pazz/projects/alot/alot/widgets/search.py", line 60, in rebuild
    width, part = build_text_part(partname, self.thread,
  File "/home/pazz/projects/alot/alot/widgets/search.py", line 145, in build_text_part
    content = prepare_string(name, thread, maxw)
  File "/home/pazz/projects/alot/alot/widgets/search.py", line 212, in prepare_string
    s = content(thread)
  File "/home/pazz/projects/alot/alot/widgets/search.py", line 177, in prepare_authors_string
    return thread.get_authors_string() or '(None)'
  File "/home/pazz/projects/alot/alot/db/thread.py", line 199, in get_authors_string
    for aname, aaddress in self.get_authors():
  File "/home/pazz/projects/alot/alot/db/thread.py", line 162, in get_authors
    msgs = sorted(self.get_messages().keys(),
  File "/home/pazz/projects/alot/alot/db/thread.py", line 248, in get_messages
    self._toplevel_messages.append(accumulate(self._messages,
  File "/home/pazz/projects/alot/alot/db/thread.py", line 243, in accumulate
    acc[M].append(accumulate(acc, m))
  File "/home/pazz/projects/alot/alot/db/thread.py", line 243, in accumulate
    acc[M].append(accumulate(acc, m))
  File "/home/pazz/projects/alot/alot/db/thread.py", line 243, in accumulate
    acc[M].append(accumulate(acc, m))
  [Previous line repeated 1 more time]
  File "/home/pazz/projects/alot/alot/db/thread.py", line 240, in accumulate
    M = Message(self._dbman, msg, thread=self)
  File "/home/pazz/projects/alot/alot/db/message.py", line 59, in __init__
    sender = decode_header(msg.header('From'))
  File "/home/pazz/projects/notmuch/bindings/python-cffi/notmuch2/_message.py", line 252, in header
    raise LookupError
LookupError
ff2000 commented 3 years ago

@flub might be able to help here.

flub commented 3 years ago

Looking at the notmuch2 code this is entirely expected, libnotmuch is returning an empty string because the header is missing and notmuch2 is turning this into a LookupError.

Comparing this with the previous python bindinds however, they did not do this check and simply decoded the empty string and returned it. Leaving it up to the caller to handle the empty string.

So you probably need to update the caller to the new API contract (which I think is more suitable for Python bindings, but let me know if you disagree).