Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions instana/instrumentation/sqlalchemy.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ def _set_error_tags(context, exception_string, scope_string):
@event.listens_for(Engine, error_event, named=True)
def receive_handle_db_error(**kw):

if get_active_tracer() is None:
return

# support older db error event
if error_event == "dbapi_error":
context = kw.get('context')
Expand Down
27 changes: 27 additions & 0 deletions tests/clients/test_sqlalchemy.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from ..helpers import testenv
from instana.singletons import tracer
from sqlalchemy.orm import sessionmaker
from sqlalchemy.exc import OperationalError
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, create_engine

Expand Down Expand Up @@ -181,3 +182,29 @@ def test_error_logging(self):
self.assertIsNotNone(sql_span.stack)
self.assertTrue(type(sql_span.stack) is list)
self.assertGreater(len(sql_span.stack), 0)

def test_error_before_tracing(self):
"""Test the scenario, in which instana is loaded,
but connection fails before tracing begins.
This is typical in test container scenario,
where it is "normal" to just start hammering a database container
which is still starting and not ready to handle requests yet.
In this scenario it is important that we get
an sqlalachemy exception, and not something else
like an AttributeError. Because testcontainer has a logic
to retry in case of certain sqlalchemy exceptions but it
can't handle an AttributeError."""
# https://github.com/instana/python-sensor/issues/362

self.assertIsNone(tracer.active_span)

invalid_connection_url = 'postgresql://user1:pwd1@localhost:9999/mydb1'
with self.assertRaisesRegex(
OperationalError,
r'\(psycopg2.OperationalError\) connection .* failed.*'
) as context_manager:
engine = create_engine(invalid_connection_url)
version, = engine.execute("select version()").fetchone()

the_exception = context_manager.exception
self.assertFalse(the_exception.connection_invalidated)
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
collect_ignore_glob.append("*test_grpc*")
collect_ignore_glob.append("*test_boto3*")
collect_ignore_glob.append("*test_stan_recorder*")
collect_ignore_glob.append("*test_sqlalchemy*")

if "ASYNQP_TEST" not in os.environ:
# if LooseVersion(sys.version) < LooseVersion('3.5.3') or LooseVersion(sys.version) >= LooseVersion('3.8.0'):
Expand Down