@@ -162,17 +162,26 @@ def get_type_module(cls):
162162 return mod
163163
164164
165+ def should_hide_frame (frame ):
166+ try :
167+ mod = frame .f_globals ["__name__" ]
168+ return mod .startswith ("sentry_sdk." )
169+ except (AttributeError , KeyError ):
170+ pass
171+
172+ for flag_name in "__traceback_hide__" , "__tracebackhide__" :
173+ try :
174+ if frame .f_locals [flag_name ]:
175+ return True
176+ except Exception :
177+ pass
178+
179+ return False
180+
181+
165182def iter_stacks (tb ):
166183 while tb is not None :
167- skip = False
168- for flag_name in "__traceback_hide__" , "__tracebackhide__" :
169- try :
170- if tb .tb_frame .f_locals [flag_name ]:
171- skip = True
172- except Exception :
173- pass
174-
175- if not skip :
184+ if not should_hide_frame (tb .tb_frame ):
176185 yield tb
177186 tb = tb .tb_next
178187
@@ -242,19 +251,6 @@ def get_source_context(frame, tb_lineno):
242251 return [], None , []
243252
244253
245- def skip_internal_frames (frame ):
246- tb = frame
247- while tb is not None :
248- try :
249- mod = tb .tb_frame .f_globals ["__name__" ]
250- if not mod .startswith ("sentry_sdk." ):
251- break
252- except (AttributeError , KeyError ):
253- pass
254- tb = tb .tb_next
255- return tb
256-
257-
258254def safe_str (value ):
259255 try :
260256 return text_type (value )
@@ -308,8 +304,7 @@ def extract_locals(frame):
308304 return rv
309305
310306
311- def frame_from_traceback (tb , with_locals = True ):
312- frame = tb .tb_frame
307+ def serialize_frame (frame , tb_lineno = None , with_locals = True ):
313308 f_code = getattr (frame , "f_code" , None )
314309 if f_code :
315310 abs_path = frame .f_code .co_filename
@@ -322,14 +317,17 @@ def frame_from_traceback(tb, with_locals=True):
322317 except Exception :
323318 module = None
324319
325- pre_context , context_line , post_context = get_source_context (frame , tb .tb_lineno )
320+ if tb_lineno is None :
321+ tb_lineno = frame .f_lineno
322+
323+ pre_context , context_line , post_context = get_source_context (frame , tb_lineno )
326324
327325 rv = {
328326 "filename" : abs_path and os .path .basename (abs_path ) or None ,
329327 "abs_path" : os .path .abspath (abs_path ),
330328 "function" : function or "<unknown>" ,
331329 "module" : module ,
332- "lineno" : tb . tb_lineno ,
330+ "lineno" : tb_lineno ,
333331 "pre_context" : pre_context ,
334332 "context_line" : context_line ,
335333 "post_context" : post_context ,
@@ -339,8 +337,30 @@ def frame_from_traceback(tb, with_locals=True):
339337 return rv
340338
341339
342- def stacktrace_from_traceback (tb , with_locals = True ):
343- return {"frames" : [frame_from_traceback (tb , with_locals ) for tb in iter_stacks (tb )]}
340+ def stacktrace_from_traceback (tb = None , with_locals = True ):
341+ return {
342+ "frames" : [
343+ serialize_frame (
344+ tb .tb_frame , tb_lineno = tb .tb_lineno , with_locals = with_locals
345+ )
346+ for tb in iter_stacks (tb )
347+ ]
348+ }
349+
350+
351+ def current_stacktrace (with_locals = True ):
352+ __tracebackhide__ = True
353+ frames = []
354+
355+ f = sys ._getframe ()
356+ while f is not None :
357+ if not should_hide_frame (f ):
358+ frames .append (serialize_frame (f , with_locals = with_locals ))
359+ f = f .f_back
360+
361+ frames .reverse ()
362+
363+ return {"frames" : frames }
344364
345365
346366def get_errno (exc_value ):
@@ -356,23 +376,19 @@ def single_exception_from_error_tuple(
356376 mechanism_meta = mechanism .setdefault ("meta" , {})
357377 mechanism_meta .setdefault ("errno" , {"code" : errno })
358378
359- rv = {
379+ if client_options is None :
380+ with_locals = True
381+ else :
382+ with_locals = client_options ["with_locals" ]
383+
384+ return {
360385 "module" : get_type_module (exc_type ),
361386 "type" : get_type_name (exc_type ),
362387 "value" : safe_str (exc_value ),
363388 "mechanism" : mechanism ,
389+ "stacktrace" : stacktrace_from_traceback (tb , with_locals ),
364390 }
365391
366- if client_options is None or client_options ["attach_stacktrace" ]:
367- if client_options is None :
368- with_locals = True
369- else :
370- with_locals = client_options ["with_locals" ]
371-
372- rv ["stacktrace" ] = stacktrace_from_traceback (tb , with_locals )
373-
374- return rv
375-
376392
377393def exceptions_from_error_tuple (exc_info , client_options = None , mechanism = None ):
378394 exc_type , exc_value , tb = exc_info
@@ -453,9 +469,6 @@ def exc_info_from_error(error):
453469 exc_value = error
454470 exc_type = type (error )
455471
456- if tb is not None :
457- tb = skip_internal_frames (tb )
458-
459472 return exc_type , exc_value , tb
460473
461474
0 commit comments