Internal helper. This calls the given command (a no-argument
    callable) with the Config instance in cfg and interprets any
    errors for the user.

def _dispatch_command(reactor, cfg, command):
    """
    Internal helper. This calls the given command (a no-argument
    callable) with the Config instance in cfg and interprets any
    errors for the user.
    """
    cfg.timing.add("command dispatch")
    cfg.timing.add(
        "import", when=start, which="top").finish(when=top_import_finish)

    try:
        yield maybeDeferred(command)
    except (WrongPasswordError, NoTorError) as e:
        msg = fill("ERROR: " + dedent(e.__doc__))
        print(msg, file=cfg.stderr)
        raise SystemExit(1)
    except (WelcomeError, UnsendableFileError, KeyFormatError) as e:
        msg = fill("ERROR: " + dedent(e.__doc__))
        print(msg, file=cfg.stderr)
        print(six.u(""), file=cfg.stderr)
        print(six.text_type(e), file=cfg.stderr)
        raise SystemExit(1)
    except TransferError as e:
        print(u"TransferError: %s" % six.text_type(e), file=cfg.stderr)
        raise SystemExit(1)
    except ServerConnectionError as e:
        msg = fill("ERROR: " + dedent(e.__doc__)) + "\n"
        msg += "(relay URL was %s)\n" % e.url
        msg += six.text_type(e)
        print(msg, file=cfg.stderr)
        raise SystemExit(1)
    except Exception as e:
        # this prints a proper traceback, whereas
        # traceback.print_exc() just prints a TB to the "yield"
        # line above ...
        Failure().printTraceback(file=cfg.stderr)
        print(u"ERROR:", six.text_type(e), file=cfg.stderr)
        raise SystemExit(1)

    cfg.timing.add("exit")
    if cfg.dump_timing:
        cfg.timing.write(cfg.dump_timing, cfg.stderr)