def formatex(ex, msg='[!?] Caught exception',
             prefix=None, key_list=[], locals_=None, iswarning=False, tb=False,
             N=0, keys=None, colored=None):
    r
    if prefix is None:
        prefix = get_caller_prefix(aserror=True, N=N)
    if locals_ is None:
        locals_ = get_parent_frame(N=N).f_locals
    if keys is not None:
        key_list = keys
    errstr_list = []
    ex_tag = 'WARNING' if iswarning else 'EXCEPTION'
    errstr_list.append('<!!! %s !!!>' % ex_tag)
    if tb or FORCE_TB:
        tbtext = traceback.format_exc()
        if colored or COLORED_EXCEPTIONS:
            from utool import util_str
            tbtext = util_str.highlight_text(tbtext, lexer_name='pytb', stripall=True)
        errstr_list.append(tbtext)
    errstr_list.append(prefix + ' ' + six.text_type(msg) + '\n%r: %s' % (type(ex), six.text_type(ex)))
    parse_locals_keylist(locals_, key_list, errstr_list, prefix)
    errstr_list.append('</!!! %s !!!>' % ex_tag)
    return '\n'.join(errstr_list)