Commit b2f34ad9 authored by Jacek Sowiński's avatar Jacek Sowiński

Don't crash on shlex.split error

Show some meaningful error messages instead.

Fixes #107
parent 3adbc019
......@@ -4,3 +4,4 @@ baz = FooBar
format = ls -F "|I| x c d {(}p{)} s k" -n 25
smile = ls
star = tag {} star 1
quot = lol'd
......@@ -21,9 +21,8 @@ from topydo.Commands import get_subcommand
from topydo.commands.AddCommand import AddCommand
from topydo.commands.DeleteCommand import DeleteCommand
from topydo.commands.ListCommand import ListCommand
from topydo.commands.ListProjectCommand import ListProjectCommand
from topydo.commands.TagCommand import TagCommand
from topydo.lib.Config import config
from topydo.lib.Config import config, ConfigError
class GetSubcommandTest(TopydoTest):
def test_normal_cmd(self):
......@@ -120,6 +119,15 @@ class GetSubcommandTest(TopydoTest):
real_cmd, final_args = get_subcommand(args)
self.assertEqual(real_cmd, None)
def test_alias_quotation(self):
config("test/data/aliases.conf")
args = ["quot"]
with self.assertRaises(ConfigError) as ce:
get_subcommand(args)
self.assertEqual(str(ce.exception), 'No closing quotation')
def test_help(self):
real_cmd, final_args = get_subcommand(['help', 'nonexisting'])
self.assertFalse(real_cmd)
......
......@@ -21,7 +21,7 @@ instance based on an argument list.
import sys
from topydo.lib.Config import config
from topydo.lib.Config import config, ConfigError
_SUBCOMMAND_MAP = {
'add': 'AddCommand',
......@@ -90,7 +90,11 @@ def get_subcommand(p_args):
If alias resolves to non-existent command, main help message is
returned.
"""
real_subcommand, alias_args = alias_map[p_alias]
try:
real_subcommand, alias_args = alias_map[p_alias]
except ValueError as ve:
raise ConfigError(alias_map[p_alias]) from ve
try:
result = import_subcommand(real_subcommand)
args = join_args(p_args, alias_args)
......
......@@ -50,7 +50,11 @@ class CLIApplication(CLIApplicationBase):
self.todofile = TodoFile.TodoFile(config().todotxt())
self.todolist = TodoList.TodoList(self.todofile.read())
(subcommand, args) = get_subcommand(args)
try:
(subcommand, args) = get_subcommand(args)
except ConfigError as ce:
error('Error: ' + str(ce) + '. Check your aliases configuration')
sys.exit(1)
if subcommand is None:
self._usage()
......
......@@ -99,9 +99,16 @@ class PromptApplication(CLIApplicationBase):
sys.exit(0)
except KeyboardInterrupt:
continue
except ValueError as verr:
error('Error: ' + str(verr))
mtime_after = _todotxt_mtime()
(subcommand, args) = get_subcommand(user_input)
try:
(subcommand, args) = get_subcommand(user_input)
except ConfigError as ce:
error('Error: ' + str(ce) + '. Check your aliases configuration')
continue
# refuse to perform operations such as 'del' and 'do' if the
# todo.txt file has been changed in the background.
......
......@@ -18,6 +18,7 @@ import configparser
import os
import shlex
class ConfigError(Exception):
def __init__(self, p_text):
self.text = p_text
......@@ -299,10 +300,13 @@ class _Config:
alias_dict = dict()
for alias, meaning in aliases:
meaning = shlex.split(meaning)
real_subcommand = meaning[0]
alias_args = meaning[1:]
alias_dict[alias] = (real_subcommand, alias_args)
try:
meaning = shlex.split(meaning)
real_subcommand = meaning[0]
alias_args = meaning[1:]
alias_dict[alias] = (real_subcommand, alias_args)
except ValueError as verr:
alias_dict[alias] = str(verr)
return alias_dict
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment