Determine the best output format based on the Accept header, execute the
    regular handler, and transform the output to the request content type (even
    if it's an error).

    :param args: Pass args through to the main handler
    :param kwargs: Pass kwargs through to the main handler

def hypermedia_handler(*args, **kwargs):
    '''
    Determine the best output format based on the Accept header, execute the
    regular handler, and transform the output to the request content type (even
    if it's an error).

    :param args: Pass args through to the main handler
    :param kwargs: Pass kwargs through to the main handler
    '''
    # Execute the real handler. Handle or pass-through any errors we know how
    # to handle (auth & HTTP errors). Reformat any errors we don't know how to
    # handle as a data structure.
    try:
        cherrypy.response.processors = dict(ct_out_map)
        ret = cherrypy.serving.request._hypermedia_inner_handler(*args, **kwargs)
    except (salt.exceptions.AuthenticationError,
            salt.exceptions.AuthorizationError,
            salt.exceptions.EauthAuthenticationError,
            salt.exceptions.TokenAuthenticationError):
        raise cherrypy.HTTPError(401)
    except salt.exceptions.SaltInvocationError:
        raise cherrypy.HTTPError(400)
    except (salt.exceptions.SaltDaemonNotRunning,
            salt.exceptions.SaltReqTimeoutError) as exc:
        raise cherrypy.HTTPError(503, exc.strerror)
    except salt.exceptions.SaltClientTimeout:
        raise cherrypy.HTTPError(504)
    except cherrypy.CherryPyException:
        raise
    except Exception as exc:
        # The TimeoutError exception class was removed in CherryPy in 12.0.0, but
        # Still check existence of TimeoutError and handle in CherryPy < 12.
        # The check was moved down from the SaltClientTimeout error line because
        # A one-line if statement throws a BaseException inheritance TypeError.
        if hasattr(cherrypy, 'TimeoutError') and isinstance(exc, cherrypy.TimeoutError):
            raise cherrypy.HTTPError(504)

        import traceback

        logger.debug("Error while processing request for: %s",
                cherrypy.request.path_info,
                exc_info=True)

        cherrypy.response.status = 500

        ret = {
            'status': cherrypy.response.status,
            'return': '{0}'.format(traceback.format_exc(exc))
                    if cherrypy.config['debug']
                    else "An unexpected error occurred"}

    # Raises 406 if requested content-type is not supported
    best = cherrypy.lib.cptools.accept([i for (i, _) in ct_out_map])

    # Transform the output from the handler into the requested output format
    cherrypy.response.headers['Content-Type'] = best
    out = cherrypy.response.processors[best]
    try:
        response = out(ret)
        if six.PY3:
            response = salt.utils.stringutils.to_bytes(response)
        return response
    except Exception:
        msg = 'Could not serialize the return data from Salt.'
        logger.debug(msg, exc_info=True)
        raise cherrypy.HTTPError(500, msg)