mirror of
https://github.com/topydo/topydo.git
synced 2024-05-20 05:48:35 +00:00
Handle errors in file I/O more gracefully
Show an error on I/O errors, permissions or Unicode decoding issues. Open issue is that errors are not printed properly in the column UI. Instead of calling CLIApplicationBase.error(), the column UI should pass on the error to the user in a way that does not involve stderr.
This commit is contained in:
parent
dea65c346c
commit
56d98b6058
|
@ -21,6 +21,9 @@ This module deals with todo.txt files.
|
|||
import codecs
|
||||
import os.path
|
||||
|
||||
class TodoFileException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class TodoFile(object):
|
||||
"""
|
||||
|
@ -38,8 +41,9 @@ class TodoFile(object):
|
|||
todofile = codecs.open(self.path, 'r', encoding="utf-8")
|
||||
todos = todofile.readlines()
|
||||
todofile.close()
|
||||
except IOError:
|
||||
pass
|
||||
except (PermissionError, IOError, UnicodeDecodeError) as err:
|
||||
raise TodoFileException('Error while reading: {}'.format(str(err))) from err
|
||||
todofile.close()
|
||||
|
||||
return todos
|
||||
|
||||
|
@ -51,14 +55,17 @@ class TodoFile(object):
|
|||
to the file.
|
||||
"""
|
||||
|
||||
todofile = codecs.open(self.path, 'w', encoding="utf-8")
|
||||
try:
|
||||
todofile = codecs.open(self.path, 'w', encoding="utf-8")
|
||||
|
||||
if p_todos is list:
|
||||
for todo in p_todos:
|
||||
todofile.write(str(todo))
|
||||
else:
|
||||
todofile.write(p_todos)
|
||||
if p_todos is list:
|
||||
for todo in p_todos:
|
||||
todofile.write(str(todo))
|
||||
else:
|
||||
todofile.write(p_todos)
|
||||
|
||||
todofile.write("\n")
|
||||
|
||||
todofile.close()
|
||||
todofile.write("\n")
|
||||
todofile.close()
|
||||
except (PermissionError, IOError) as err:
|
||||
raise TodoFileException('Error while writing: {}'.format(str(err))) from err
|
||||
todofile.close()
|
||||
|
|
|
@ -23,6 +23,7 @@ import getopt
|
|||
import sys
|
||||
|
||||
from topydo.lib.Color import AbstractColor, Color
|
||||
from topydo.lib.TodoFile import TodoFileException
|
||||
from topydo.lib.TopydoString import TopydoString
|
||||
|
||||
MAIN_OPTS = "ac:C:d:ht:v"
|
||||
|
@ -157,7 +158,12 @@ def _retrieve_archive():
|
|||
and the second element is a TodoFile.
|
||||
"""
|
||||
archive_file = TodoFile.TodoFile(config().archive())
|
||||
archive = TodoListBase.TodoListBase(archive_file.read())
|
||||
|
||||
try:
|
||||
archive = TodoListBase.TodoListBase(archive_file.read())
|
||||
except TodoFileException as err:
|
||||
error('Could not read archive file: {}.'.format(err))
|
||||
archive = None
|
||||
|
||||
return (archive, archive_file)
|
||||
|
||||
|
@ -234,7 +240,10 @@ class CLIApplicationBase(object):
|
|||
command.execute()
|
||||
|
||||
if archive.dirty:
|
||||
archive_file.write(archive.print_todos())
|
||||
try:
|
||||
archive_file.write(archive.print_todos())
|
||||
except TodoFileException as err:
|
||||
error('Item(s) could not be archived: {}'.format(str(err)))
|
||||
|
||||
def _help(self, args):
|
||||
if args is None:
|
||||
|
@ -298,8 +307,12 @@ class CLIApplicationBase(object):
|
|||
if self.backup:
|
||||
self.backup.save(self.todolist)
|
||||
|
||||
self.todofile.write(self.todolist.print_todos())
|
||||
self.todolist.dirty = False
|
||||
try:
|
||||
self.todofile.write(self.todolist.print_todos())
|
||||
self.todolist.dirty = False
|
||||
except TodoFileException as err:
|
||||
error(str(err))
|
||||
error('The last operation could not be saved.')
|
||||
|
||||
self.backup = None
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
import sys
|
||||
|
||||
from topydo.ui.CLIApplicationBase import CLIApplicationBase, error
|
||||
from topydo.lib import TodoFile
|
||||
from topydo.lib.TodoFile import TodoFile, TodoFileException
|
||||
from topydo.lib.Config import config, ConfigError
|
||||
|
||||
# First thing is to poke the configuration and check whether it's sane
|
||||
|
@ -32,7 +32,7 @@ except ConfigError as config_error:
|
|||
sys.exit(1)
|
||||
|
||||
from topydo.Commands import get_subcommand
|
||||
from topydo.lib import TodoList
|
||||
from topydo.lib.TodoList import TodoList
|
||||
|
||||
|
||||
class CLIApplication(CLIApplicationBase):
|
||||
|
@ -47,8 +47,12 @@ class CLIApplication(CLIApplicationBase):
|
|||
""" Main entry function. """
|
||||
args = self._process_flags()
|
||||
|
||||
self.todofile = TodoFile.TodoFile(config().todotxt())
|
||||
self.todolist = TodoList.TodoList(self.todofile.read())
|
||||
self.todofile = TodoFile(config().todotxt())
|
||||
|
||||
try:
|
||||
self.todolist = TodoList(self.todofile.read())
|
||||
except TodoFileException as err:
|
||||
error('Could not read todo file: {}'.format(str(err)))
|
||||
|
||||
try:
|
||||
(subcommand, args) = get_subcommand(args)
|
||||
|
|
|
@ -30,8 +30,9 @@ from topydo.lib.Sorter import Sorter
|
|||
from topydo.lib.Filter import get_filter_list, RelevanceFilter, DependencyFilter
|
||||
from topydo.lib.Utils import get_terminal_size
|
||||
from topydo.lib.View import View
|
||||
from topydo.lib.TodoFile import TodoFileException
|
||||
from topydo.lib.TodoFileWatched import TodoFileWatched
|
||||
from topydo.lib import TodoList
|
||||
from topydo.lib.TodoList import TodoList
|
||||
from topydo.ui.CLIApplicationBase import CLIApplicationBase, error, GENERIC_HELP
|
||||
from topydo.ui.columns.CommandLineWidget import CommandLineWidget
|
||||
from topydo.ui.columns.ConsoleWidget import ConsoleWidget
|
||||
|
@ -110,14 +111,26 @@ class UIApplication(CLIApplicationBase):
|
|||
self.alt_layout_path = value
|
||||
|
||||
def callback():
|
||||
self.todolist.erase()
|
||||
self.todolist.add_list(self.todofile.read())
|
||||
self._update_all_columns()
|
||||
self._redraw()
|
||||
try:
|
||||
todos = self.todofile.read()
|
||||
self.todolist.erase()
|
||||
self.todolist.add_list(todos)
|
||||
self._update_all_columns()
|
||||
self._redraw()
|
||||
except TodoFileException as err:
|
||||
self._print_to_console(
|
||||
'Error: Could not read todo file: {}'.format(err))
|
||||
|
||||
self.column_width = config().column_width()
|
||||
self.todofile = TodoFileWatched(config().todotxt(), callback)
|
||||
self.todolist = TodoList.TodoList(self.todofile.read())
|
||||
|
||||
try:
|
||||
todos = self.todofile.read()
|
||||
except TodoFileException as err:
|
||||
error('Error: Could not read todo file: {}'.format(err))
|
||||
sys.exit(1)
|
||||
|
||||
self.todolist = TodoList(todos)
|
||||
|
||||
self.marked_todos = set()
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import os.path
|
|||
import shlex
|
||||
import sys
|
||||
|
||||
from topydo.lib.TodoFile import TodoFileException
|
||||
from topydo.ui.CLIApplicationBase import CLIApplicationBase, error, GENERIC_HELP
|
||||
from topydo.ui.prompt.TopydoCompleter import TopydoCompleter
|
||||
from prompt_toolkit.shortcuts import prompt
|
||||
|
@ -60,7 +61,12 @@ class PromptApplication(CLIApplicationBase):
|
|||
instance.
|
||||
"""
|
||||
self.todolist.erase()
|
||||
self.todolist.add_list(self.todofile.read())
|
||||
|
||||
try:
|
||||
self.todolist.add_list(self.todofile.read())
|
||||
except TodoFileException as err:
|
||||
error('Could not read todo file: {}'.format(str(err)))
|
||||
|
||||
self.completer = TopydoCompleter(self.todolist)
|
||||
|
||||
def run(self):
|
||||
|
|
Loading…
Reference in a new issue