def safe_repr(obj, max_length=None, repr=repr):
    """
    A safe version of repr that is guaranteed to never raise exceptions.
    """
    # noinspection PyBroadException
    try:
        data = repr(obj)
    except Exception as ex:
        cls_name = type(obj).__name__
        ex_name = type(ex).__name__
        data = f"<{cls_name} object [{ex_name}: {ex}]>"

    if max_length is not None and len(data) > max_length:
        data = data[: max_length - 3] + "..."

    return data