GothenburgBitFactory / tasklib

A Python library for interacting with taskwarrior databases.
http://tasklib.readthedocs.org/en/latest/
BSD 3-Clause "New" or "Revised" License
147 stars 28 forks source link

Error handling difficult, lazy loading issue? #81

Closed thehunmonkgroup closed 4 years ago

thehunmonkgroup commented 4 years ago

I'm the developer of VIT, which leverages tasklib for some of its work.

I'm running into a difficulty properly catching errors. Take this block of code:

        try:
            self.tasks = self.tw.tasks.filter(filters) if filters else self.tw.tasks.all()
        except TaskWarriorException as err:
            raise VitException(err)

It's possible the user could pass an invalid filter that would result in a TaskWarriorException being thrown. However, the block does not properly catch the error, because it's thrown later, apparently the first time self.tasks is actually accessed in any way.

For example, if I do this:

        try:
            self.tasks = self.tw.tasks.filter(filters) if filters else self.tw.tasks.all()
            len(self.tasks)
        except TaskWarriorException as err:
            raise VitException(err)

Then the try/catch works properly. But that's a very odd thing to do to make a try/except block work.

What's the cleanest way to solve this issue?

robgolding commented 4 years ago

Hey @thehunmonkgroup! Sorry this is causing confusion. It's pretty important for performance though, so unfortunately I think the behaviour is going to stay the same for the foreseeable future.

However, if you want to force an evaluation of the filter in order to store the resulting tasks somewhere (e.g. self.tasks), you could simply wrap the call in list(). This is what we do in the tests: https://github.com/robgolding/tasklib/blob/develop/tasklib/tests.py#L221.

thehunmonkgroup commented 4 years ago

Sounds like I've already basically got the best approach. Thanks for the clarification!