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