Clean up command exception handling
This commit is contained in:
parent
689723508f
commit
995a0d19cc
@ -228,7 +228,7 @@ class QuteBrowser(QApplication):
|
|||||||
for e in self._args.command:
|
for e in self._args.command:
|
||||||
if e.startswith(':'):
|
if e.startswith(':'):
|
||||||
logging.debug("Startup cmd {}".format(e))
|
logging.debug("Startup cmd {}".format(e))
|
||||||
self.commandmanager.run(e.lstrip(':'))
|
self.commandmanager.run_safely(e.lstrip(':'))
|
||||||
else:
|
else:
|
||||||
logging.debug("Startup url {}".format(e))
|
logging.debug("Startup url {}".format(e))
|
||||||
self._opened_urls.append(e)
|
self._opened_urls.append(e)
|
||||||
@ -273,7 +273,7 @@ class QuteBrowser(QApplication):
|
|||||||
modeman.manager.key_pressed.connect(status.on_key_pressed)
|
modeman.manager.key_pressed.connect(status.on_key_pressed)
|
||||||
|
|
||||||
# commands
|
# commands
|
||||||
cmd.got_cmd.connect(self.commandmanager.run)
|
cmd.got_cmd.connect(self.commandmanager.run_safely)
|
||||||
cmd.got_search.connect(self.searchmanager.search)
|
cmd.got_search.connect(self.searchmanager.search)
|
||||||
cmd.got_search_rev.connect(self.searchmanager.search_rev)
|
cmd.got_search_rev.connect(self.searchmanager.search_rev)
|
||||||
cmd.returnPressed.connect(tabs.setFocus)
|
cmd.returnPressed.connect(tabs.setFocus)
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from qutebrowser.commands._exceptions import (ArgumentCountError,
|
from qutebrowser.commands._exceptions import (ArgumentCountError,
|
||||||
InvalidModeError, NeedsJSError)
|
PrerequisitesError)
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, QObject
|
from PyQt5.QtCore import pyqtSignal, QObject
|
||||||
from PyQt5.QtWebKit import QWebSettings
|
from PyQt5.QtWebKit import QWebSettings
|
||||||
@ -83,19 +83,22 @@ class Command(QObject):
|
|||||||
|
|
||||||
Raise:
|
Raise:
|
||||||
ArgumentCountError if the argument count is wrong.
|
ArgumentCountError if the argument count is wrong.
|
||||||
InvalidModeError if the command can't be called in this mode.
|
PrerequisitesError if the command can't be called currently.
|
||||||
"""
|
"""
|
||||||
import qutebrowser.keyinput.modeman as modeman
|
import qutebrowser.keyinput.modeman as modeman
|
||||||
if self.modes is not None and modeman.manager.mode not in self.modes:
|
if self.modes is not None and modeman.manager.mode not in self.modes:
|
||||||
raise InvalidModeError("This command is only allowed in {} "
|
raise PrerequisitesError("{}: This command is only allowed in {} "
|
||||||
"mode.".format('/'.join(self.modes)))
|
"mode.".format(self.name,
|
||||||
|
'/'.join(self.modes)))
|
||||||
elif (self.not_modes is not None and
|
elif (self.not_modes is not None and
|
||||||
modeman.manager.mode in self.not_modes):
|
modeman.manager.mode in self.not_modes):
|
||||||
raise InvalidModeError("This command is not allowed in {} "
|
raise PrerequisitesError("{}: This command is not allowed in {} "
|
||||||
"mode.".format('/'.join(self.not_modes)))
|
"mode.".format(self.name,
|
||||||
|
'/'.join(self.not_modes)))
|
||||||
if self.needs_js and not QWebSettings.globalSettings().testAttribute(
|
if self.needs_js and not QWebSettings.globalSettings().testAttribute(
|
||||||
QWebSettings.JavascriptEnabled):
|
QWebSettings.JavascriptEnabled):
|
||||||
raise NeedsJSError
|
raise PrerequisitesError("{}: This command needs javascript "
|
||||||
|
"enabled.".format(self.name))
|
||||||
if self.nargs[1] is None and self.nargs[0] <= len(args):
|
if self.nargs[1] is None and self.nargs[0] <= len(args):
|
||||||
pass
|
pass
|
||||||
elif self.nargs[0] <= len(args) <= self.nargs[1]:
|
elif self.nargs[0] <= len(args) <= self.nargs[1]:
|
||||||
|
@ -21,29 +21,31 @@ Defined here to avoid circular dependency hell.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class NoSuchCommandError(ValueError):
|
class CommandError(Exception):
|
||||||
|
|
||||||
|
"""Common base class for all command exceptions."""
|
||||||
|
|
||||||
|
|
||||||
|
class NoSuchCommandError(CommandError):
|
||||||
|
|
||||||
"""Raised when a command wasn't found."""
|
"""Raised when a command wasn't found."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ArgumentCountError(TypeError):
|
class ArgumentCountError(CommandError):
|
||||||
|
|
||||||
"""Raised when a command was called with an invalid count of arguments."""
|
"""Raised when a command was called with an invalid count of arguments."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InvalidModeError(Exception):
|
class PrerequisitesError(CommandError):
|
||||||
|
|
||||||
"""Raised when a command is called in a wrong input mode."""
|
"""Raised when a cmd can't be used because some prerequisites aren't met.
|
||||||
|
|
||||||
pass
|
This is raised for example when we're in the wrong mode while executing the
|
||||||
|
command, or we need javascript enabled but don't have done so.
|
||||||
|
"""
|
||||||
class NeedsJSError(Exception):
|
|
||||||
|
|
||||||
"""Raised when a command needs javascript but it is disabled."""
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
@ -23,8 +23,7 @@ from PyQt5.QtWebKitWidgets import QWebPage
|
|||||||
import qutebrowser.config.config as config
|
import qutebrowser.config.config as config
|
||||||
import qutebrowser.commands.utils as cmdutils
|
import qutebrowser.commands.utils as cmdutils
|
||||||
import qutebrowser.utils.message as message
|
import qutebrowser.utils.message as message
|
||||||
from qutebrowser.commands._exceptions import (
|
from qutebrowser.commands._exceptions import NoSuchCommandError, CommandError
|
||||||
ArgumentCountError, NoSuchCommandError, InvalidModeError, NeedsJSError)
|
|
||||||
|
|
||||||
|
|
||||||
def split_cmdline(text):
|
def split_cmdline(text):
|
||||||
@ -162,7 +161,7 @@ class CommandManager:
|
|||||||
try:
|
try:
|
||||||
cmd = cmdutils.cmd_dict[cmdstr]
|
cmd = cmdutils.cmd_dict[cmdstr]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise NoSuchCommandError(cmdstr)
|
raise NoSuchCommandError('{}: no such command'.format(cmdstr))
|
||||||
|
|
||||||
if len(parts) == 1:
|
if len(parts) == 1:
|
||||||
args = []
|
args = []
|
||||||
@ -187,59 +186,24 @@ class CommandManager:
|
|||||||
else:
|
else:
|
||||||
self._cmd.run(self._args)
|
self._cmd.run(self._args)
|
||||||
|
|
||||||
@pyqtSlot(str, int, bool)
|
def run(self, text, count=None):
|
||||||
def run(self, text, count=None, ignore_exc=True):
|
|
||||||
"""Parse a command from a line of text.
|
"""Parse a command from a line of text.
|
||||||
|
|
||||||
If ignore_exc is True, ignore exceptions and return True/False.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
text: The text to parse.
|
text: The text to parse.
|
||||||
count: The count to pass to the command.
|
count: The count to pass to the command.
|
||||||
ignore_exc: Ignore exceptions and return False instead.
|
|
||||||
|
|
||||||
Raise:
|
|
||||||
NoSuchCommandError: if a command wasn't found.
|
|
||||||
ArgumentCountError: if a command was called with the wrong count of
|
|
||||||
arguments.
|
|
||||||
InvalidModeError: if a command can't be called in this mode.
|
|
||||||
|
|
||||||
Return:
|
|
||||||
True if command was called (handler returnstatus is ignored!).
|
|
||||||
False if command wasn't called (there was an ignored exception).
|
|
||||||
"""
|
"""
|
||||||
if ';;' in text:
|
if ';;' in text:
|
||||||
retvals = []
|
|
||||||
for sub in text.split(';;'):
|
for sub in text.split(';;'):
|
||||||
retvals.append(self.run(sub, count, ignore_exc))
|
self.run(sub, count)
|
||||||
return all(retvals)
|
|
||||||
try:
|
|
||||||
self.parse(text)
|
self.parse(text)
|
||||||
self._check()
|
self._check()
|
||||||
except NoSuchCommandError as e:
|
|
||||||
if ignore_exc:
|
|
||||||
message.error("{}: no such command".format(e))
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
except ArgumentCountError as e:
|
|
||||||
if ignore_exc:
|
|
||||||
message.error("{}: invalid argument count - {}".format(
|
|
||||||
self._cmd.name, e))
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
except InvalidModeError as e:
|
|
||||||
if ignore_exc:
|
|
||||||
message.error("{}: {}".format(self._cmd.name, e))
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
except NeedsJSError as e:
|
|
||||||
if ignore_exc:
|
|
||||||
message.error("{}: {}".format(self._cmd.name, e))
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
self._run(count=count)
|
self._run(count=count)
|
||||||
return True
|
|
||||||
|
@pyqtSlot(str, int)
|
||||||
|
def run_safely(self, text, count=None):
|
||||||
|
"""Run a command and display exceptions in the statusbar."""
|
||||||
|
try:
|
||||||
|
self.run(text, count)
|
||||||
|
except CommandError as e:
|
||||||
|
message.error(str(e))
|
||||||
|
@ -22,8 +22,8 @@ import logging
|
|||||||
from qutebrowser.keyinput._basekeyparser import BaseKeyParser
|
from qutebrowser.keyinput._basekeyparser import BaseKeyParser
|
||||||
import qutebrowser.utils.message as message
|
import qutebrowser.utils.message as message
|
||||||
|
|
||||||
from qutebrowser.commands.managers import (CommandManager, ArgumentCountError,
|
from qutebrowser.commands.managers import CommandManager
|
||||||
NoSuchCommandError)
|
from qutebrowser.commands._exceptions import ArgumentCountError, CommandError
|
||||||
|
|
||||||
|
|
||||||
class CommandKeyParser(BaseKeyParser):
|
class CommandKeyParser(BaseKeyParser):
|
||||||
@ -39,25 +39,24 @@ class CommandKeyParser(BaseKeyParser):
|
|||||||
super().__init__(parent, supports_count, supports_chains)
|
super().__init__(parent, supports_count, supports_chains)
|
||||||
self.commandmanager = CommandManager()
|
self.commandmanager = CommandManager()
|
||||||
|
|
||||||
def _run_or_fill(self, cmdstr, count=None, ignore_exc=True):
|
def _run_or_fill(self, cmdstr, count=None):
|
||||||
"""Run the command in cmdstr or fill the statusbar if args missing.
|
"""Run the command in cmdstr or fill the statusbar if args missing.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
cmdstr: The command string.
|
cmdstr: The command string.
|
||||||
count: Optional command count.
|
count: Optional command count.
|
||||||
ignore_exc: Ignore exceptions.
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.commandmanager.run(cmdstr, count=count, ignore_exc=ignore_exc)
|
self.commandmanager.run(cmdstr, count=count)
|
||||||
except NoSuchCommandError:
|
|
||||||
pass
|
|
||||||
except ArgumentCountError:
|
except ArgumentCountError:
|
||||||
logging.debug("Filling statusbar with partial command {}".format(
|
logging.debug("Filling statusbar with partial command {}".format(
|
||||||
cmdstr))
|
cmdstr))
|
||||||
message.set_cmd_text(':{} '.format(cmdstr))
|
message.set_cmd_text(':{} '.format(cmdstr))
|
||||||
|
except CommandError as e:
|
||||||
|
message.error(str(e))
|
||||||
|
|
||||||
def execute(self, cmdstr, _keytype, count=None):
|
def execute(self, cmdstr, _keytype, count=None):
|
||||||
self._run_or_fill(cmdstr, count, ignore_exc=False)
|
self._run_or_fill(cmdstr, count)
|
||||||
|
|
||||||
|
|
||||||
class PassthroughKeyParser(CommandKeyParser):
|
class PassthroughKeyParser(CommandKeyParser):
|
||||||
|
Loading…
Reference in New Issue
Block a user