def capture()

in elasticapm/events.py [0:0]


    def capture(client, exc_info=None, **kwargs):
        culprit = exc_value = exc_type = exc_module = frames = exc_traceback = None
        new_exc_info = False
        if not exc_info or exc_info is True:
            new_exc_info = True
            exc_info = sys.exc_info()

        if exc_info == (None, None, None):
            raise ValueError("No exception found: capture_exception requires an active exception.")

        try:
            exc_type, exc_value, exc_traceback = exc_info

            frames = get_stack_info(
                iter_traceback_frames(exc_traceback, config=client.config),
                with_locals=client.config.collect_local_variables in ("errors", "all"),
                library_frame_context_lines=client.config.source_lines_error_library_frames,
                in_app_frame_context_lines=client.config.source_lines_error_app_frames,
                include_paths_re=client.include_paths_re,
                exclude_paths_re=client.exclude_paths_re,
                locals_processor_func=lambda local_var: varmap(
                    lambda k, val: shorten(
                        val,
                        list_length=client.config.local_var_list_max_length,
                        string_length=client.config.local_var_max_length,
                        dict_length=client.config.local_var_dict_max_length,
                    ),
                    local_var,
                ),
            )

            culprit = kwargs.get("culprit", None) or get_culprit(
                frames, client.config.include_paths, client.config.exclude_paths
            )

            if hasattr(exc_type, "__module__"):
                exc_module = exc_type.__module__
                exc_type = exc_type.__name__
            else:
                exc_module = None
                exc_type = exc_type.__name__
        finally:
            if new_exc_info:
                try:
                    del exc_info
                    del exc_traceback
                except Exception as e:
                    logger.exception(e)
        if "message" in kwargs:
            message = kwargs["message"]
        else:
            message = "%s: %s" % (exc_type, to_unicode(exc_value)) if exc_value else str(exc_type)

        message = encoding.long_field(message)

        data = {
            "id": "%032x" % random.getrandbits(128),
            "culprit": keyword_field(culprit),
            "exception": {
                "message": message,
                "type": keyword_field(str(exc_type)),
                "module": keyword_field(str(exc_module)),
                "stacktrace": frames,
            },
        }
        if hasattr(exc_value, "_elastic_apm_span_id"):
            data["parent_id"] = exc_value._elastic_apm_span_id
            del exc_value._elastic_apm_span_id
        depth = kwargs.get("_exc_chain_depth", 0)
        if depth > EXCEPTION_CHAIN_MAX_DEPTH:
            return
        cause = exc_value.__cause__
        chained_context = exc_value.__context__

        # we follow the pattern of Python itself here and only capture the chained exception
        # if cause is not None and __suppress_context__ is False
        if chained_context and not (exc_value.__suppress_context__ and cause is None):
            if cause:
                chained_exc_type = type(cause)
                chained_exc_value = cause
            else:
                chained_exc_type = type(chained_context)
                chained_exc_value = chained_context
            chained_exc_info = chained_exc_type, chained_exc_value, chained_context.__traceback__

            chained_cause = Exception.capture(
                client, exc_info=chained_exc_info, culprit="None", _exc_chain_depth=depth + 1
            )
            if chained_cause:
                data["exception"]["cause"] = [chained_cause["exception"]]
        return data