def unhandled_exception(e):
    """Handler method for exceptions that escape the route code without being caught.

    A consistent error page is returned.

    Due to the lack of information available to provide to the user, and the fact there was clearly
    no opportunity for cleanup or error handling in the processing code, this should be a never-event!
    """

    current_app.logger.exception("Unhandled Exception: %s", repr(e))

    http_code = 500

    try:
        # Negotiate based on the Accept header
        if request_wants_json():
            return jsonify({}), http_code
        else:
            return (
                render_template(
                    "errors/unhandled.html",
                    http_code=http_code,
                ),
                http_code,
            )
    except Exception:
        # Ultimate fallback handler, such as if jinja templates are missing
        return "Internal server error", 500
def application_error(e):
    """Handler method for ApplicationErrors raised for to inform the user of a specific scenario."""

    # Determine whether to log at info|error, when the http code being returned is not 500
    # (500s are always considered live-log worthy, at error level)
    if e.http_code == 500:
        current_app.logger.exception(
            "Application Exception (message: %s, code: %s): %s", e.message,
            e.code, repr(e))
    elif e.force_logging:
        current_app.logger.info(
            "Application Exception (message: %s, code: %s): %s",
            e.message,
            e.code,
            repr(e),
            exc_info=True)
    else:
        current_app.logger.debug(
            "Application Exception (message: %s, code: %s): %s",
            e.message,
            e.code,
            repr(e),
            exc_info=True)

    # ApplicationError allows developers to specify an HTTP code.
    # This will be written to the logs correctly, but we don't want to allow
    # this code through to the user as it may expose internal workings of the system
    # (See OWASP guidelines on error handling)
    if e.http_code in [500, 404, 403, 429]:
        http_code = e.http_code
    else:
        http_code = 500

    if request_wants_json():
        return jsonify({"message": e.message, "code": e.code}), http_code
    else:
        try:
            return (
                render_template(
                    "errors/application/{}.html".format(e.code),
                    description=e.message,
                    code=e.code,
                    http_code=http_code,
                    e=e,
                ),
                http_code,
            )
        except TemplateNotFound:
            return (
                render_template("errors/application.html",
                                description=e.message,
                                code=e.code,
                                http_code=http_code),
                http_code,
            )
Esempio n. 3
0
def http_exception(e):
    current_app.logger.exception('HTTP Exception at %s:  %s',
                                 request.full_path, repr(e))

    # Restrict error codes to a subset so that we don't inadvertently expose
    # internal system information via error codes
    if isinstance(e, HTTPException) and e.code in [500, 404, 403, 429]:
        http_code = e.code
    else:
        http_code = 500

    # Negotiate based on the Accept header
    if request_wants_json():
        return jsonify({}), http_code
    else:
        return render_template(
            'app/errors/unhandled.html',
            http_code=http_code,
        ), http_code
 def test_content_negotiation_util_returns_true_for_application_json(self):
     with self.app:
         self.app.get("/", headers=[("Accept", "application/json")])
         assert request_wants_json() is True
 def test_content_negotiation_util_returns_false_for_text_html(self):
     with self.app:
         self.app.get("/", headers=[("Accept", "text/html")])
         assert request_wants_json() is False