@@ -3165,7 +3165,7 @@ def test_suppress_scopes(exporter: TestExporter, metrics_reader: InMemoryMetricR
31653165 )
31663166
31673167
3168- def test_logfire_span_records_exceptions_once ():
3168+ def test_logfire_span_records_exceptions_once (exporter : TestExporter ):
31693169 n_calls_to_record_exception = 0
31703170
31713171 def patched_record_exception (* args : Any , ** kwargs : Any ) -> Any :
@@ -3182,6 +3182,87 @@ def patched_record_exception(*args: Any, **kwargs: Any) -> Any:
31823182 raise RuntimeError ('error' )
31833183
31843184 assert n_calls_to_record_exception == 1
3185+ assert exporter .exported_spans_as_dict () == snapshot (
3186+ [
3187+ {
3188+ 'name' : 'foo' ,
3189+ 'context' : {'trace_id' : 1 , 'span_id' : 1 , 'is_remote' : False },
3190+ 'parent' : None ,
3191+ 'start_time' : 1000000000 ,
3192+ 'end_time' : 3000000000 ,
3193+ 'attributes' : {
3194+ 'code.filepath' : 'test_logfire.py' ,
3195+ 'code.function' : 'test_logfire_span_records_exceptions_once' ,
3196+ 'code.lineno' : 123 ,
3197+ 'logfire.msg_template' : 'foo' ,
3198+ 'logfire.msg' : 'foo' ,
3199+ 'logfire.span_type' : 'span' ,
3200+ 'logfire.level_num' : 17 ,
3201+ },
3202+ 'events' : [
3203+ {
3204+ 'name' : 'exception' ,
3205+ 'timestamp' : 2000000000 ,
3206+ 'attributes' : {
3207+ 'exception.type' : 'RuntimeError' ,
3208+ 'exception.message' : 'error' ,
3209+ 'exception.stacktrace' : 'RuntimeError: error' ,
3210+ 'exception.escaped' : 'True' ,
3211+ },
3212+ }
3213+ ],
3214+ }
3215+ ]
3216+ )
3217+
3218+
3219+ def test_logfire_span_records_exceptions_manually_once (exporter : TestExporter ):
3220+ n_calls_to_record_exception = 0
3221+
3222+ def patched_record_exception (* args : Any , ** kwargs : Any ) -> Any :
3223+ nonlocal n_calls_to_record_exception
3224+ n_calls_to_record_exception += 1
3225+
3226+ return record_exception (* args , ** kwargs )
3227+
3228+ with patch ('logfire._internal.tracer.record_exception' , patched_record_exception ), patch (
3229+ 'logfire._internal.main.record_exception' , patched_record_exception
3230+ ):
3231+ with logfire .span ('foo' ) as span :
3232+ span .record_exception (RuntimeError ('error' ))
3233+
3234+ assert n_calls_to_record_exception == 1
3235+ assert exporter .exported_spans_as_dict () == snapshot (
3236+ [
3237+ {
3238+ 'name' : 'foo' ,
3239+ 'context' : {'trace_id' : 1 , 'span_id' : 1 , 'is_remote' : False },
3240+ 'parent' : None ,
3241+ 'start_time' : 1000000000 ,
3242+ 'end_time' : 2000000000 ,
3243+ 'attributes' : {
3244+ 'code.filepath' : 'test_logfire.py' ,
3245+ 'code.function' : 'test_logfire_span_records_exceptions_manually_once' ,
3246+ 'code.lineno' : 123 ,
3247+ 'logfire.msg_template' : 'foo' ,
3248+ 'logfire.msg' : 'foo' ,
3249+ 'logfire.span_type' : 'span' ,
3250+ },
3251+ 'events' : [
3252+ {
3253+ 'name' : 'exception' ,
3254+ 'timestamp' : IsInt (),
3255+ 'attributes' : {
3256+ 'exception.type' : 'RuntimeError' ,
3257+ 'exception.message' : 'error' ,
3258+ 'exception.stacktrace' : 'RuntimeError: error' ,
3259+ 'exception.escaped' : 'False' ,
3260+ },
3261+ }
3262+ ],
3263+ }
3264+ ]
3265+ )
31853266
31863267
31873268def test_exit_ended_span (exporter : TestExporter ):
0 commit comments