Exemple #1
0
 def capture_error(self, error):
     self.error = error
     self.status_code = extract_status_code(error)
     self.success = 0 < self.status_code < 400
     include_stack_trace = extract_include_stack_trace(error)
     self.stack_trace = format_exc(
         limit=10) if (not self.success and include_stack_trace) else None
Exemple #2
0
    def handle(self, error):
        """
        Generates a response that follows connexion's error format i.e.,

        "status": http status code,
        "title": Short description,
        "detail": "detail message",
        "type": "An absolute URI that identifies the problem type.
          When dereferenced, it SHOULD provide human-readable documentation for the problem type"

        Note: Heavily inspired by the microcosm_flask.errors module just needed a different format
        """
        status = extract_status_code(error)
        title = self.extract_title(error)
        detail = extract_error_message(error)
        type_name = "about:blank"

        # To make sure that we have some stack trace for 500+ errors
        if status >= 500:
            self.logger.exception(error)

        self.logger.debug(
            "Handling error {} with status {}, title {}, detail {}, type_name {}"
            .format(
                error,
                status,
                title,
                detail,
                type_name,
            ))

        response_data = {
            "status": status,
            "title": title,
            "detail": detail,
            "type": type_name,
        }

        return dump_response_data(None, response_data, status)
Exemple #3
0
 def label_error(self, error):
     status_code = extract_status_code(error)
     return str(status_code)
Exemple #4
0
def _audit_request(options, func, request_context, *args,
                   **kwargs):  # noqa: C901
    """
    Run a request function under audit.

    """
    logger = getLogger("audit")

    response = None

    # always include these fields
    audit_dict = dict(
        operation=request.endpoint,
        func=func.__name__,
        method=request.method,
    )

    # include request body on debug (if any)
    if all((
            current_app.debug,
            options.include_request_body,
            request.get_json(force=True, silent=True),
    )):
        request_body = request.get_json(force=True)
    else:
        request_body = None

    response_body = None

    # include headers (conditionally)
    if request_context is not None:
        audit_dict.update(request_context())

    # process the request
    try:
        with elapsed_time(audit_dict):
            response = func(*args, **kwargs)
    except Exception as error:
        status_code = extract_status_code(error)
        success = 0 < status_code < 400
        audit_dict.update(
            success=success,
            message=extract_error_message(error)[:2048],
            context=extract_context(error),
            stack_trace=None if success else format_exc(limit=10),
            status_code=status_code,
        )
        raise
    else:
        body, status_code = parse_response(response)

        audit_dict.update(
            success=True,
            status_code=status_code,
        )

        # include response body on debug (if any)
        if all((
                current_app.debug,
                options.include_response_body,
                body,
        )):
            try:
                response_body = loads(body)
            except (TypeError, ValueError):
                # not json
                audit_dict["response_body"] = body

        return response
    finally:
        # determine whether to show/hide body based on the g values set during func
        if not g.get("hide_body"):
            if request_body:
                for field in g.get("hide_request_fields", []):
                    try:
                        del request_body[field]
                    except KeyError:
                        pass
                audit_dict["request_body"] = request_body

            if response_body:
                for field in g.get("hide_response_fields", []):
                    try:
                        del response_body[field]
                    except KeyError:
                        pass
                audit_dict["response_body"] = response_body

        # always log at INFO; a raised exception can be an error or expected behavior (e.g. 404)
        if not should_skip_logging(func):
            logger.info(audit_dict)
Exemple #5
0
 def label_error(self, error):
     status_code = extract_status_code(error)
     return self.normalize_status_code(status_code)