From f3acb135e723258bd4b6072d5737d52e13d47054 Mon Sep 17 00:00:00 2001 From: Christopher Larson Date: Sun, 27 Jan 2013 15:41:20 -0800 Subject: bitbake: command: add error to return of runCommand Currently, command.py can return an error message from runCommand, due to being unable to run the command, yet few of our UIs (just hob) can handle it today. This can result in seeing a TypeError with traceback in certain rare circumstances. To resolve this, we need a clean way to get errors back from runCommand, without having to isinstance() the return value. This implements such a thing by making runCommand also return an error (or None if no error occurred). As runCommand now has a method of returning errors, we can also alter the getCmdLineAction bits such that the returned value is just the action, not an additional message. If a sync command wants to return an error, it raises CommandError(message), and the message will be passed to the caller appropriately. Example Usage: result, error = server.runCommand(...) if error: log.error('Unable to run command: %s' % error) return 1 (Bitbake rev: 717831b8315cb3904d9b590e633000bc897e8fb6) Signed-off-by: Christopher Larson Signed-off-by: Richard Purdie --- bitbake/lib/bb/command.py | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) (limited to 'bitbake/lib/bb/command.py') diff --git a/bitbake/lib/bb/command.py b/bitbake/lib/bb/command.py index fd8912ab40..00b854e240 100644 --- a/bitbake/lib/bb/command.py +++ b/bitbake/lib/bb/command.py @@ -44,6 +44,9 @@ class CommandFailed(CommandExit): self.error = message CommandExit.__init__(self, 1) +class CommandError(Exception): + pass + class Command: """ A queue of asynchronous commands for bitbake @@ -57,21 +60,25 @@ class Command: self.currentAsyncCommand = None def runCommand(self, commandline): - try: - command = commandline.pop(0) - if command in CommandsSync.__dict__: - # Can run synchronous commands straight away - return getattr(CommandsSync, command)(self.cmds_sync, self, commandline) - if self.currentAsyncCommand is not None: - return "Busy (%s in progress)" % self.currentAsyncCommand[0] - if command not in CommandsAsync.__dict__: - return "No such command" - self.currentAsyncCommand = (command, commandline) - self.cooker.server_registration_cb(self.cooker.runCommands, self.cooker) - return True - except: - import traceback - return traceback.format_exc() + command = commandline.pop(0) + if hasattr(CommandsSync, command): + # Can run synchronous commands straight away + command_method = getattr(self.cmds_sync, command) + try: + result = command_method(self, commandline) + except CommandError as exc: + return None, exc.args[0] + except Exception: + return None, traceback.format_exc() + else: + return result, None + if self.currentAsyncCommand is not None: + return None, "Busy (%s in progress)" % self.currentAsyncCommand[0] + if command not in CommandsAsync.__dict__: + return None, "No such command" + self.currentAsyncCommand = (command, commandline) + self.cooker.server_registration_cb(self.cooker.runCommands, self.cooker) + return True, None def runAsyncCommand(self): try: @@ -139,7 +146,11 @@ class CommandsSync: """ Get any command parsed from the commandline """ - return command.cooker.commandlineAction + cmd_action = command.cooker.commandlineAction + if cmd_action['msg']: + raise CommandError(msg) + else: + return cmd_action['action'] def getVariable(self, command, params): """ -- cgit v1.2.3-54-g00ecf