Skip to content

Commit b144219

Browse files
rsalmondc24t
authored andcommitted
Don't set status on null span in flask (census-instrumentation#464)
Don't attempt to attach exception info from flask when the current span is null.
1 parent cb0de24 commit b144219

2 files changed

Lines changed: 50 additions & 18 deletions

File tree

opencensus/trace/ext/flask/flask_middleware.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -260,18 +260,21 @@ def _teardown_request(self, exception):
260260

261261
if exception is not None:
262262
span = execution_context.get_current_span()
263-
span.status = status.Status(
264-
code=code_pb2.UNKNOWN,
265-
message=str(exception)
266-
)
267-
# try attaching the stack trace to the span, only populated if
268-
# the app has 'PROPAGATE_EXCEPTIONS', 'DEBUG', or 'TESTING'
269-
# enabled
270-
exc_type, _, exc_traceback = sys.exc_info()
271-
if exc_traceback is not None:
272-
span.stack_trace = stack_trace.StackTrace.from_traceback(
273-
exc_traceback
263+
if span is not None:
264+
span.status = status.Status(
265+
code=code_pb2.UNKNOWN,
266+
message=str(exception)
274267
)
268+
# try attaching the stack trace to the span, only populated
269+
# if the app has 'PROPAGATE_EXCEPTIONS', 'DEBUG', or
270+
# 'TESTING' enabled
271+
exc_type, _, exc_traceback = sys.exc_info()
272+
if exc_traceback is not None:
273+
span.stack_trace = (
274+
stack_trace.StackTrace.from_traceback(
275+
exc_traceback
276+
)
277+
)
275278

276279
tracer.end_span()
277280
tracer.finish()

tests/unit/trace/ext/flask/test_flask_middleware.py

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,32 @@
1717

1818
import unittest
1919

20+
from google.rpc import code_pb2
2021
import flask
2122
import mock
22-
from google.rpc import code_pb2
2323

2424
from opencensus.trace import execution_context
25-
from opencensus.trace import span_data
2625
from opencensus.trace import span as span_module
26+
from opencensus.trace import span_data
2727
from opencensus.trace import stack_trace
2828
from opencensus.trace import status
29-
from opencensus.trace.exporters import print_exporter, stackdriver_exporter, \
30-
zipkin_exporter, jaeger_exporter
29+
from opencensus.trace.blank_span import BlankSpan
30+
from opencensus.trace.exporters import jaeger_exporter
31+
from opencensus.trace.exporters import print_exporter
32+
from opencensus.trace.exporters import stackdriver_exporter
33+
from opencensus.trace.exporters import zipkin_exporter
3134
from opencensus.trace.exporters.ocagent import trace_exporter
3235
from opencensus.trace.ext.flask import flask_middleware
3336
from opencensus.trace.propagation import google_cloud_format
3437
from opencensus.trace.samplers import always_off, always_on, ProbabilitySampler
38+
from opencensus.trace.span_context import SpanContext
39+
from opencensus.trace.trace_options import TraceOptions
3540
from opencensus.trace.tracers import base
3641
from opencensus.trace.tracers import noop_tracer
37-
from opencensus.trace.blank_span import BlankSpan
42+
43+
44+
class FlaskTestException(Exception):
45+
pass
3846

3947

4048
class TestFlaskMiddleware(unittest.TestCase):
@@ -53,7 +61,7 @@ def health_check():
5361

5462
@app.route('/error')
5563
def error():
56-
raise Exception('error')
64+
raise FlaskTestException('error')
5765

5866
return app
5967

@@ -458,7 +466,7 @@ def test_teardown_include_exception_and_traceback(self):
458466
app = self.create_app()
459467
app.config['TESTING'] = True
460468
flask_middleware.FlaskMiddleware(app=app, exporter=mock_exporter)
461-
with self.assertRaises(Exception):
469+
with self.assertRaises(FlaskTestException):
462470
app.test_client().get('/error')
463471

464472
exported_spandata = mock_exporter.export.call_args[0][0][0]
@@ -471,3 +479,24 @@ def test_teardown_include_exception_and_traceback(self):
471479
)
472480
self.assertIsNotNone(exported_spandata.stack_trace.stack_trace_hash_id)
473481
self.assertNotEqual(exported_spandata.stack_trace.stack_frames, [])
482+
483+
def test_teardown_include_exception_and_traceback_span_disabled(self):
484+
sampler = always_off.AlwaysOffSampler()
485+
app = self.create_app()
486+
app.config['TESTING'] = True
487+
middleware = flask_middleware.FlaskMiddleware(app=app, sampler=sampler)
488+
489+
# TODO: send trace options in header (#465)
490+
original_method = middleware.propagator.from_headers
491+
492+
def nope(*args, **kwargs):
493+
trace_options = TraceOptions()
494+
trace_options.set_enabled(False)
495+
return SpanContext(trace_options=trace_options)
496+
497+
middleware.propagator.from_headers = nope
498+
499+
with self.assertRaises(FlaskTestException):
500+
app.test_client().get('/error')
501+
502+
middleware.propagator.from_headers = original_method

0 commit comments

Comments
 (0)