Skip to content

Commit b6b1773

Browse files
authored
Sanic exception bug fix (#338)
* fixing bug causing out of index * added one additional test case
1 parent 1844a2c commit b6b1773

File tree

4 files changed

+109
-12
lines changed

4 files changed

+109
-12
lines changed

instana/instrumentation/sanic_inst.py

+13-9
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,21 @@
1717

1818
@wrapt.patch_function_wrapper('sanic.exceptions', 'SanicException.__init__')
1919
def exception_with_instana(wrapped, instance, args, kwargs):
20-
message = kwargs.get("message", args[0])
21-
status_code = kwargs.get("status_code")
22-
span = async_tracer.active_span
20+
try:
21+
message = kwargs.get("message") or args[0]
22+
status_code = kwargs.get("status_code")
23+
span = async_tracer.active_span
2324

24-
if all([span, status_code, message]) and (500 <= status_code <= 599):
25-
span.set_tag("http.error", message)
26-
try:
25+
if all([span, status_code, message]) and (500 <= status_code <= 599):
26+
span.set_tag("http.error", message)
27+
try:
28+
wrapped(*args, **kwargs)
29+
except Exception as exc:
30+
span.log_exception(exc)
31+
else:
2732
wrapped(*args, **kwargs)
28-
except Exception as exc:
29-
span.log_exception(exc)
30-
else:
33+
except Exception:
34+
logger.debug("exception_with_instana: ", exc_info=True)
3135
wrapped(*args, **kwargs)
3236

3337

instana/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33

44
# Module version file. Used by setup.py and snapshot reporting.
55

6-
VERSION = '1.35.3'
6+
VERSION = '1.35.4'

tests/apps/sanic_app/server.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# (c) Copyright IBM Corp. 2021
22
# (c) Copyright Instana Inc. 2021
33

4+
import instana
5+
46
from sanic import Sanic
57
from sanic.exceptions import SanicException
68
from tests.apps.sanic_app.simpleview import SimpleView
79
from tests.apps.sanic_app.name import NameView
810
from sanic.response import text
9-
import instana
1011

1112
app = Sanic('test')
1213

@@ -19,6 +20,13 @@ async def uuid_handler(request, foo_id: int):
1920
async def test_request_args(request):
2021
raise SanicException("Something went wrong.", status_code=500)
2122

23+
@app.route("/instana_exception")
24+
async def test_request_args(request):
25+
raise SanicException(description="Something went wrong.", status_code=500)
26+
27+
@app.route("/wrong")
28+
async def test_request_args(request):
29+
raise SanicException(message="Something went wrong.", status_code=400)
2230

2331
@app.get("/tag/<tag>")
2432
async def tag_handler(request, tag):

tests/frameworks/test_sanic.py

+86-1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,92 @@ def test_404(self):
127127
assert (asgi_span.data['http']['error'] is None)
128128
assert (asgi_span.data['http']['params'] is None)
129129

130+
def test_sanic_exception(self):
131+
result = None
132+
with tracer.start_active_span('test'):
133+
result = requests.get(testenv["sanic_server"] + '/wrong')
134+
135+
self.assertEqual(result.status_code, 400)
136+
137+
spans = tracer.recorder.queued_spans()
138+
self.assertEqual(len(spans), 3)
139+
140+
span_filter = lambda span: span.n == "sdk" and span.data['sdk']['name'] == 'test'
141+
test_span = get_first_span_by_filter(spans, span_filter)
142+
self.assertIsNotNone(test_span)
143+
144+
span_filter = lambda span: span.n == "urllib3"
145+
urllib3_span = get_first_span_by_filter(spans, span_filter)
146+
self.assertIsNotNone(urllib3_span)
147+
148+
span_filter = lambda span: span.n == 'asgi'
149+
asgi_span = get_first_span_by_filter(spans, span_filter)
150+
self.assertIsNotNone(asgi_span)
151+
152+
self.assertTraceContextPropagated(test_span, urllib3_span)
153+
self.assertTraceContextPropagated(urllib3_span, asgi_span)
154+
155+
self.assertIn("X-INSTANA-T", result.headers)
156+
self.assertEqual(result.headers["X-INSTANA-T"], asgi_span.t)
157+
self.assertIn("X-INSTANA-S", result.headers)
158+
self.assertEqual(result.headers["X-INSTANA-S"], asgi_span.s)
159+
self.assertIn("X-INSTANA-L", result.headers)
160+
self.assertEqual(result.headers["X-INSTANA-L"], '1')
161+
self.assertIn("Server-Timing", result.headers)
162+
self.assertEqual(result.headers["Server-Timing"], ("intid;desc=%s" % asgi_span.t))
163+
164+
self.assertIsNone(asgi_span.ec)
165+
assert (asgi_span.data['http']['host'] == '127.0.0.1:1337')
166+
assert (asgi_span.data['http']['path'] == '/wrong')
167+
assert (asgi_span.data['http']['path_tpl'] == '/wrong')
168+
assert (asgi_span.data['http']['method'] == 'GET')
169+
assert (asgi_span.data['http']['status'] == 400)
170+
assert (asgi_span.data['http']['error'] is None)
171+
assert (asgi_span.data['http']['params'] is None)
172+
173+
def test_500_instana_exception(self):
174+
result = None
175+
with tracer.start_active_span('test'):
176+
result = requests.get(testenv["sanic_server"] + '/instana_exception')
177+
178+
self.assertEqual(result.status_code, 500)
179+
180+
spans = tracer.recorder.queued_spans()
181+
self.assertEqual(len(spans), 4)
182+
183+
span_filter = lambda span: span.n == "sdk" and span.data['sdk']['name'] == 'test'
184+
test_span = get_first_span_by_filter(spans, span_filter)
185+
self.assertIsNotNone(test_span)
186+
187+
span_filter = lambda span: span.n == "urllib3"
188+
urllib3_span = get_first_span_by_filter(spans, span_filter)
189+
self.assertIsNotNone(urllib3_span)
190+
191+
span_filter = lambda span: span.n == 'asgi'
192+
asgi_span = get_first_span_by_filter(spans, span_filter)
193+
self.assertIsNotNone(asgi_span)
194+
195+
self.assertTraceContextPropagated(test_span, urllib3_span)
196+
self.assertTraceContextPropagated(urllib3_span, asgi_span)
197+
198+
self.assertIn("X-INSTANA-T", result.headers)
199+
self.assertEqual(result.headers["X-INSTANA-T"], asgi_span.t)
200+
self.assertIn("X-INSTANA-S", result.headers)
201+
self.assertEqual(result.headers["X-INSTANA-S"], asgi_span.s)
202+
self.assertIn("X-INSTANA-L", result.headers)
203+
self.assertEqual(result.headers["X-INSTANA-L"], '1')
204+
self.assertIn("Server-Timing", result.headers)
205+
self.assertEqual(result.headers["Server-Timing"], ("intid;desc=%s" % asgi_span.t))
206+
207+
self.assertEqual(asgi_span.ec, 1)
208+
assert (asgi_span.data['http']['host'] == '127.0.0.1:1337')
209+
assert (asgi_span.data['http']['path'] == '/instana_exception')
210+
assert (asgi_span.data['http']['path_tpl'] == '/instana_exception')
211+
assert (asgi_span.data['http']['method'] == 'GET')
212+
assert (asgi_span.data['http']['status'] == 500)
213+
assert (asgi_span.data['http']['error'] is None)
214+
assert (asgi_span.data['http']['params'] is None)
215+
130216
def test_500(self):
131217
result = None
132218
with tracer.start_active_span('test'):
@@ -213,7 +299,6 @@ def test_path_templates(self):
213299
assert (asgi_span.data['http']['error'] is None)
214300
assert (asgi_span.data['http']['params'] is None)
215301

216-
217302
def test_secret_scrubbing(self):
218303
result = None
219304
with tracer.start_active_span('test'):

0 commit comments

Comments
 (0)