# Buggy code
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.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 (cherrypy.TimeoutError, salt.exceptions.SaltClientTimeout):
        raise cherrypy.HTTPError(504)
    except cherrypy.CherryPyException:
        raise
    except Exception as exc:
        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.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)


# Traceback (AttributeError)
# ./tests/runtests.py -n integration.netapi.rest_cherrypy.test_app
<snipped>
ERROR: test_webhook_noauth (integration.netapi.rest_cherrypy.test_app.TestWebhookDisableAuth)
[CPU:91.3%|MEM:35.6%]
----------------------------------------------------------------------
Traceback (most recent call last):
File "/root/SaltStack/salt/tests/support/cherrypy_testclasses.py", line 86, in setUp
root, apiopts, conf = app.get_app(base_opts)
File "/root/SaltStack/salt/salt/netapi/rest_cherrypy/app.py", line 2790, in get_app
cpyopts = root.get_conf()  # cherrypy app opts
File "/root/SaltStack/salt/salt/netapi/rest_cherrypy/app.py", line 2774, in get_conf
cherrypy.config.update(conf['global'])
File "/usr/local/lib/python2.7/dist-packages/cherrypy/_cpconfig.py", line 154, in update
reprconf.Config.update(self, config)
File "/usr/local/lib/python2.7/dist-packages/cherrypy/lib/reprconf.py", line 158, in update
self._apply(config)
File "/usr/local/lib/python2.7/dist-packages/cherrypy/_cpconfig.py", line 164, in _apply
reprconf.Config._apply(self, config)
File "/usr/local/lib/python2.7/dist-packages/cherrypy/lib/reprconf.py", line 170, in _apply
self.namespaces(config)
File "/usr/local/lib/python2.7/dist-packages/cherrypy/lib/reprconf.py", line 112, in __call__
handler(k, v)
File "/usr/local/lib/python2.7/dist-packages/cherrypy/_cpconfig.py", line 272, in _engine_namespace_handler
plugin = getattr(engine, plugin)
AttributeError: 'Bus' object has no attribute 'timeout_monitor'

# Fixed code
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.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 (
        cherrypy.TimeoutError if hasattr(cherrypy, "TimeoutError") else None,
        salt.exceptions.SaltClientTimeout,
    ):
        raise cherrypy.HTTPError(504)
    except cherrypy.CherryPyException:
        raise
    except Exception as exc:
        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.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)