Suppose I have an exception e, and I would like to format it for logging/printing:
def format_exception(e):
    # type: (Exception) -> Text
    """Log formatter used in a catch-all near the edge."""
    return str(e)  # Python 2.7 only
Specifically, I want to get the exception message - the equivalent of e.message in Python 2.6, or str(e) in Python 2.7.
I have tried
return six_text_type(e)
However, that fails if e.message contains encoded bytes (which, given that I am working in a py2-py3 environment, can happen.)
>>> six.text_type(MyError(u''))   # OK
>>> six.text_type(MyError(u''.encode('utf-8')))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf0 in position 0: ordinal not in range(128)
traceback.format_exception_only (from related question) does almost the right thing (handles both bytes and unicode), but it forces me to split on :. It also doesn't help that format_exception_only returns a byte string in python2, and a unicode string in python3.
# python2
>>> type(traceback.format_exception_only(type(e), e)[0])
str
# python3
>>> type(traceback.format_exception_only(type(e), e)[0])
str
So that doesn't quite work. Wrapping that in six.text_type again fails if e.message contains encoded bytes.
What's the right way to fill in format_exception? Do I really need to use traceback2?
def format_exception(e):
    # type: (Exception) -> Text
    return traceback2.format_exception_only(type(e), e)[0].split(': ')[1]
I can install and use traceback2, but it feels like there should be a better way.
