# Buggy code
def __str__(self):
    return " :: ".join(
        part
        for part in (self.typ, self.description, self.detail, self.title)
        if part is not None
    )


# Traceback (UnicodeEncodeError)
2017-02-28 16:06:00,465:INFO:certbot.auth_handler:Cleaning up challenges
2017-02-28 16:06:00,465:DEBUG:certbot.plugins.webroot:Removing /etc/letsencrypt/webroot/.well-known/acme-challenge/Olybbkj6iWuPN5MrNF7tAAIGrGyh8Ddy22F0TAoQaRE
2017-02-28 16:06:00,466:DEBUG:certbot.plugins.webroot:Removing /etc/letsencrypt/webroot/.well-known/acme-challenge/5o1e3MiNU8gmtuV_Etz44dwhwQXdFbgR86cZhIHU04c
2017-02-28 16:06:00,467:DEBUG:certbot.plugins.webroot:Removing /etc/letsencrypt/webroot/.well-known/acme-challenge/8kKTJhJa6T5wYMWrEwfr7x1wO2FtcNPMaTTMA27z1uA
2017-02-28 16:06:00,467:DEBUG:certbot.plugins.webroot:All challenges cleaned up, removing /etc/letsencrypt/webroot/.well-known/acme-challenge
2017-02-28 16:06:00,469:DEBUG:certbot.main:Exiting abnormally:
Traceback (most recent call last):
File "/root/.local/share/letsencrypt/bin/letsencrypt", line 11, in <module>
sys.exit(main())
File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/certbot/main.py", line 882, in main
return config.func(config, plugins)
File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/certbot/main.py", line 659, in obtain_cert
action, _ = _auth_from_available(le_client, config, domains, certname, lineage)
File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/certbot/main.py", line 104, in _auth_from_available
renewal.renew_cert(config, domains, le_client, lineage)
File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/certbot/renewal.py", line 296, in renew_cert
new_certr, new_chain, new_key, _ = le_client.obtain_certificate(domains)
File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/certbot/client.py", line 265, in obtain_certificate
self.config.allow_subset_of_names)
File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/certbot/auth_handler.py", line 77, in get_authorizations
self._respond(resp, best_effort)
File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/certbot/auth_handler.py", line 134, in _respond
self._poll_challenges(chall_update, best_effort)
File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/certbot/auth_handler.py", line 197, in _poll_challenges
_report_failed_challs(all_failed_achalls)
File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/certbot/auth_handler.py", line 488, in _report_failed_challs
_generate_failed_chall_msg(achalls), reporter.MEDIUM_PRIORITY)
File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/certbot/auth_handler.py", line 504, in _generate_failed_chall_msg
if messages.is_acme_error(error):
File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/acme/messages.py", line 39, in is_acme_error
return (ERROR_PREFIX in str(err)) or (OLD_ERROR_PREFIX in str(err))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 276-280: ordinal not in range(128)

# Fixed code
def __str__(self):
    return b" :: ".join(
        part.encode("ascii", "backslashreplace")
        for part in (self.typ, self.description, self.detail, self.title)
        if part is not None
    ).decode()