Skip to content

Commit

Permalink
Sanic exception bug fix (#338)
Browse files Browse the repository at this point in the history
* fixing bug causing out of index

* added one additional test case
  • Loading branch information
pdimitra authored Oct 4, 2021
1 parent 1844a2c commit b6b1773
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 12 deletions.
22 changes: 13 additions & 9 deletions instana/instrumentation/sanic_inst.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,21 @@

@wrapt.patch_function_wrapper('sanic.exceptions', 'SanicException.__init__')
def exception_with_instana(wrapped, instance, args, kwargs):
message = kwargs.get("message", args[0])
status_code = kwargs.get("status_code")
span = async_tracer.active_span
try:
message = kwargs.get("message") or args[0]
status_code = kwargs.get("status_code")
span = async_tracer.active_span

if all([span, status_code, message]) and (500 <= status_code <= 599):
span.set_tag("http.error", message)
try:
if all([span, status_code, message]) and (500 <= status_code <= 599):
span.set_tag("http.error", message)
try:
wrapped(*args, **kwargs)
except Exception as exc:
span.log_exception(exc)
else:
wrapped(*args, **kwargs)
except Exception as exc:
span.log_exception(exc)
else:
except Exception:
logger.debug("exception_with_instana: ", exc_info=True)
wrapped(*args, **kwargs)


Expand Down
2 changes: 1 addition & 1 deletion instana/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@

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

VERSION = '1.35.3'
VERSION = '1.35.4'
10 changes: 9 additions & 1 deletion tests/apps/sanic_app/server.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# (c) Copyright IBM Corp. 2021
# (c) Copyright Instana Inc. 2021

import instana

from sanic import Sanic
from sanic.exceptions import SanicException
from tests.apps.sanic_app.simpleview import SimpleView
from tests.apps.sanic_app.name import NameView
from sanic.response import text
import instana

app = Sanic('test')

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

@app.route("/instana_exception")
async def test_request_args(request):
raise SanicException(description="Something went wrong.", status_code=500)

@app.route("/wrong")
async def test_request_args(request):
raise SanicException(message="Something went wrong.", status_code=400)

@app.get("/tag/<tag>")
async def tag_handler(request, tag):
Expand Down
87 changes: 86 additions & 1 deletion tests/frameworks/test_sanic.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,92 @@ def test_404(self):
assert (asgi_span.data['http']['error'] is None)
assert (asgi_span.data['http']['params'] is None)

def test_sanic_exception(self):
result = None
with tracer.start_active_span('test'):
result = requests.get(testenv["sanic_server"] + '/wrong')

self.assertEqual(result.status_code, 400)

spans = tracer.recorder.queued_spans()
self.assertEqual(len(spans), 3)

span_filter = lambda span: span.n == "sdk" and span.data['sdk']['name'] == 'test'
test_span = get_first_span_by_filter(spans, span_filter)
self.assertIsNotNone(test_span)

span_filter = lambda span: span.n == "urllib3"
urllib3_span = get_first_span_by_filter(spans, span_filter)
self.assertIsNotNone(urllib3_span)

span_filter = lambda span: span.n == 'asgi'
asgi_span = get_first_span_by_filter(spans, span_filter)
self.assertIsNotNone(asgi_span)

self.assertTraceContextPropagated(test_span, urllib3_span)
self.assertTraceContextPropagated(urllib3_span, asgi_span)

self.assertIn("X-INSTANA-T", result.headers)
self.assertEqual(result.headers["X-INSTANA-T"], asgi_span.t)
self.assertIn("X-INSTANA-S", result.headers)
self.assertEqual(result.headers["X-INSTANA-S"], asgi_span.s)
self.assertIn("X-INSTANA-L", result.headers)
self.assertEqual(result.headers["X-INSTANA-L"], '1')
self.assertIn("Server-Timing", result.headers)
self.assertEqual(result.headers["Server-Timing"], ("intid;desc=%s" % asgi_span.t))

self.assertIsNone(asgi_span.ec)
assert (asgi_span.data['http']['host'] == '127.0.0.1:1337')
assert (asgi_span.data['http']['path'] == '/wrong')
assert (asgi_span.data['http']['path_tpl'] == '/wrong')
assert (asgi_span.data['http']['method'] == 'GET')
assert (asgi_span.data['http']['status'] == 400)
assert (asgi_span.data['http']['error'] is None)
assert (asgi_span.data['http']['params'] is None)

def test_500_instana_exception(self):
result = None
with tracer.start_active_span('test'):
result = requests.get(testenv["sanic_server"] + '/instana_exception')

self.assertEqual(result.status_code, 500)

spans = tracer.recorder.queued_spans()
self.assertEqual(len(spans), 4)

span_filter = lambda span: span.n == "sdk" and span.data['sdk']['name'] == 'test'
test_span = get_first_span_by_filter(spans, span_filter)
self.assertIsNotNone(test_span)

span_filter = lambda span: span.n == "urllib3"
urllib3_span = get_first_span_by_filter(spans, span_filter)
self.assertIsNotNone(urllib3_span)

span_filter = lambda span: span.n == 'asgi'
asgi_span = get_first_span_by_filter(spans, span_filter)
self.assertIsNotNone(asgi_span)

self.assertTraceContextPropagated(test_span, urllib3_span)
self.assertTraceContextPropagated(urllib3_span, asgi_span)

self.assertIn("X-INSTANA-T", result.headers)
self.assertEqual(result.headers["X-INSTANA-T"], asgi_span.t)
self.assertIn("X-INSTANA-S", result.headers)
self.assertEqual(result.headers["X-INSTANA-S"], asgi_span.s)
self.assertIn("X-INSTANA-L", result.headers)
self.assertEqual(result.headers["X-INSTANA-L"], '1')
self.assertIn("Server-Timing", result.headers)
self.assertEqual(result.headers["Server-Timing"], ("intid;desc=%s" % asgi_span.t))

self.assertEqual(asgi_span.ec, 1)
assert (asgi_span.data['http']['host'] == '127.0.0.1:1337')
assert (asgi_span.data['http']['path'] == '/instana_exception')
assert (asgi_span.data['http']['path_tpl'] == '/instana_exception')
assert (asgi_span.data['http']['method'] == 'GET')
assert (asgi_span.data['http']['status'] == 500)
assert (asgi_span.data['http']['error'] is None)
assert (asgi_span.data['http']['params'] is None)

def test_500(self):
result = None
with tracer.start_active_span('test'):
Expand Down Expand Up @@ -213,7 +299,6 @@ def test_path_templates(self):
assert (asgi_span.data['http']['error'] is None)
assert (asgi_span.data['http']['params'] is None)


def test_secret_scrubbing(self):
result = None
with tracer.start_active_span('test'):
Expand Down

0 comments on commit b6b1773

Please sign in to comment.