# Buggy code
def _handle_exception(exc_type, exc_value, trace, config):
    """Logs exceptions and reports them to the user.

    Config is used to determine how to display exceptions to the user. In
    general, if config.debug is True, then the full exception and traceback is
    shown to the user, otherwise it is suppressed. If config itself is None,
    then the traceback and exception is attempted to be written to a logfile.
    If this is successful, the traceback is suppressed, otherwise it is shown
    to the user. sys.exit is always called with a nonzero status.

    """
    logger.debug(
        "Exiting abnormally:%s%s",
        os.linesep,
        "".join(traceback.format_exception(exc_type, exc_value, trace)),
    )

    if issubclass(exc_type, Exception) and (config is None or not config.debug):
        if config is None:
            logfile = "certbot.log"
            try:
                with open(logfile, "w") as logfd:
                    traceback.print_exception(exc_type, exc_value, trace, file=logfd)
            except:  # pylint: disable=bare-except
                sys.exit(
                    "".join(traceback.format_exception(exc_type, exc_value, trace))
                )

        if issubclass(exc_type, errors.Error):
            sys.exit(exc_value)
        else:
            # Here we're passing a client or ACME error out to the client at the shell
            # Tell the user a bit about what happened, without overwhelming
            # them with a full traceback
            err = traceback.format_exception_only(exc_type, exc_value)[0]
            # Typical error from the ACME module:
            # acme.messages.Error: urn:acme:error:malformed :: The request message was
            # malformed :: Error creating new registration :: Validation of contact
            # mailto:none@longrandomstring.biz failed: Server failure at resolver
            if (
                "urn:acme" in err
                and ":: " in err
                and config.verbose_count <= cli.flag_default("verbose_count")
            ):
                # prune ACME error code, we have a human description
                _code, _sep, err = err.partition(":: ")
            msg = "An unexpected error occurred:\n" + err + "Please see the "
            if config is None:
                msg += "logfile '{0}' for more details.".format(logfile)
            else:
                msg += "logfiles in {0} for more details.".format(config.logs_dir)
            sys.exit(msg)
    else:
        sys.exit("".join(traceback.format_exception(exc_type, exc_value, trace)))


# Traceback (errors.NoInstallationError)
2016-04-11 18:31:36,104:DEBUG:letsencrypt.main:Root logging level set at 30
2016-04-11 18:31:36,105:INFO:letsencrypt.main:Saving debug log to /var/log/letsencrypt/letsencrypt.log
2016-04-11 18:31:36,105:DEBUG:letsencrypt.main:letsencrypt version: 0.6.0.dev0
2016-04-11 18:31:36,105:DEBUG:letsencrypt.main:Arguments: []
2016-04-11 18:31:36,106:DEBUG:letsencrypt.main:Discovered plugins: PluginsRegistry(PluginEntryPoint#nginx,PluginEntryPoint#standalone,PluginEntryPoint#manual,PluginEntryPoint#webroot,PluginEntryPoint#apache,PluginEntryPoint#null)
2016-04-11 18:31:36,109:DEBUG:letsencrypt.plugins.selection:Requested authenticator None and installer None
2016-04-11 18:31:36,430:DEBUG:letsencrypt.plugins.disco:No installation (PluginEntryPoint#nginx):
Traceback (most recent call last):
File "/root/letsencrypt/letsencrypt/plugins/disco.py", line 104, in prepare
self._initialized.prepare()
File "/root/letsencrypt/letsencrypt-nginx/letsencrypt_nginx/configurator.py", line 115, in prepare
raise errors.NoInstallationError
NoInstallationError
2016-04-11 18:31:36,430:DEBUG:letsencrypt.plugins.selection:Single candidate plugin: * apache
Description: Apache Web Server - Alpha
Interfaces: IAuthenticator, IInstaller, IPlugin
Entry point: apache = letsencrypt_apache.configurator:ApacheConfigurator
Initialized: <letsencrypt_apache.configurator.ApacheConfigurator object at 0x7fc63206bc10>
Prep: True
2016-04-11 18:31:36,431:DEBUG:letsencrypt.plugins.selection:Selected authenticator <letsencrypt_apache.configurator.ApacheConfigurator object at 0x7fc63206bc10> and installer <letsencrypt_apache.configurator.ApacheConfigurator object at 0x7fc63206bc10>
2016-04-11 18:31:38,909:DEBUG:letsencrypt.main:Exiting abnormally:
Traceback (most recent call last):
File "/root/letsencrypt/venv/bin/letsencrypt", line 9, in <module>
load_entry_point('letsencrypt', 'console_scripts', 'letsencrypt')()
File "/root/letsencrypt/letsencrypt/main.py", line 692, in main
return config.func(config, plugins)
File "/root/letsencrypt/letsencrypt/main.py", line 452, in run
domains = _find_domains(config, installer)
File "/root/letsencrypt/letsencrypt/main.py", line 261, in _find_domains
domains = display_ops.choose_names(installer)
File "/root/letsencrypt/letsencrypt/display/ops.py", line 100, in choose_names
return _choose_names_manually()
File "/root/letsencrypt/letsencrypt/display/ops.py", line 150, in _choose_names_manually
cli_flag="--domains")
File "/root/letsencrypt/letsencrypt/display/util.py", line 146, in input
return self.dialog.inputbox(message, width=self.width, height=height)
File "/root/letsencrypt/venv/local/lib/python2.7/site-packages/dialog.py", line 2715, in inputbox
kwargs, strip_xdialog_newline=True, raw_help=True)
File "/root/letsencrypt/venv/local/lib/python2.7/site-packages/dialog.py", line 1746, in _widget_with_string_output
code, output = self._perform(args, **kwargs)
File "/root/letsencrypt/venv/local/lib/python2.7/site-packages/dialog.py", line 1541, in _perform
args_file)
File "/root/letsencrypt/venv/local/lib/python2.7/site-packages/dialog.py", line 1502, in _handle_program_exit
child_output_rfd)
File "/root/letsencrypt/venv/local/lib/python2.7/site-packages/dialog.py", line 1454, in _wait_for_program_termination
child_output.strip()))
DialogError

# Fixed code
def _handle_exception(exc_type, exc_value, trace, config):
    """Logs exceptions and reports them to the user.

    Config is used to determine how to display exceptions to the user. In
    general, if config.debug is True, then the full exception and traceback is
    shown to the user, otherwise it is suppressed. If config itself is None,
    then the traceback and exception is attempted to be written to a logfile.
    If this is successful, the traceback is suppressed, otherwise it is shown
    to the user. sys.exit is always called with a nonzero status.

    """
    logger.debug(
        "Exiting abnormally:%s%s",
        os.linesep,
        "".join(traceback.format_exception(exc_type, exc_value, trace)),
    )

    if issubclass(exc_type, Exception) and (config is None or not config.debug):
        if config is None:
            logfile = "certbot.log"
            try:
                with open(logfile, "w") as logfd:
                    traceback.print_exception(exc_type, exc_value, trace, file=logfd)
            except:  # pylint: disable=bare-except
                sys.exit(
                    "".join(traceback.format_exception(exc_type, exc_value, trace))
                )

        if issubclass(exc_type, errors.Error):
            sys.exit(exc_value)
        else:
            # Here we're passing a client or ACME error out to the client at the shell
            # Tell the user a bit about what happened, without overwhelming
            # them with a full traceback
            if issubclass(exc_type, dialog.error):
                err = exc_value.complete_message()
            else:
                err = traceback.format_exception_only(exc_type, exc_value)[0]
            # Typical error from the ACME module:
            # acme.messages.Error: urn:acme:error:malformed :: The request message was
            # malformed :: Error creating new registration :: Validation of contact
            # mailto:none@longrandomstring.biz failed: Server failure at resolver
            if (
                "urn:acme" in err
                and ":: " in err
                and config.verbose_count <= cli.flag_default("verbose_count")
            ):
                # prune ACME error code, we have a human description
                _code, _sep, err = err.partition(":: ")
            msg = "An unexpected error occurred:\n" + err + "Please see the "
            if config is None:
                msg += "logfile '{0}' for more details.".format(logfile)
            else:
                msg += "logfiles in {0} for more details.".format(config.logs_dir)
            sys.exit(msg)
    else:
        sys.exit("".join(traceback.format_exception(exc_type, exc_value, trace)))