I have Sentry set up for a Python application that we're using internally.
The Sentry exception ticket has the following attributes:
Traceback (most recent call last):Traceback (most recent call last):
File "/percolate/analytics/pegasus/pegasus/services/aquarius/service.py", line 28, in Query
resp = builder.build()
File "/percolate/analytics/pegasus/pegasus/services/aquarius/builder.py", line 235, in build
q = self.apply_sort(q)
File "/percolate/analytics/pegasus/pegasus/services/aquarius/builder.py", line 225, in apply_sort
sorts = [s.apply_sort(self.selects) for s in self.sort]
File "/percolate/analytics/pegasus/pegasus/services/aquarius/builder.py", line 225, in <listcomp>
sorts = [s.apply_sort(self.selects) for s in self.sort]
AttributeError: 'NumericField' object has no attribute 'apply_sort'
See the following screen capture:

I see a number of exceptions in the Sentry UI with the same Traceback: ... name instead of the specific exception name. Is there a reason why this is the case?
Here's the code that triggers these exceptions:
try:
query_result = q.execution_options(timeout=PEGASUS_QUERY_TIMEOUT).all()
except Exception as e:
if sentry_client:
with sentry_client.configure_scope() as scope:
compiled_query = q.statement.compile(
dialect=postgresql.dialect()
)
scope.set_extra("query", str(compiled_query))
scope.set_extra("params", str(compiled_query.params))
raise e
It's not clear if I'm using the Sentry client closing context correctly, or if this is an actual issue within the Sentry SDK. Thank you for your help in advance!
Where do you actually capture the error? In the snippet you showed me you only attach some data to the current scope, which you can do anytime. Your code is equivalent to:
if sentry_client:
with sentry_client.configure_scope() as scope:
compiled_query = q.statement.compile(
dialect=postgresql.dialect()
)
scope.set_extra("query", str(compiled_query))
scope.set_extra("params", str(compiled_query.params))
query_result = q.execution_options(timeout=PEGASUS_QUERY_TIMEOUT).all()
I think you're logging a stringified version of the traceback, and not the actual exception. It seems that you at some point catch down the error and log to pegasus.services.aquarius.service. This could also happen within the task queue or web framework that calls this code.
By the way, your Sentry server is very old and I urge you to upgrade.
@untitaker hi, thanks for the quick response!
In the code snippet, you'll see the try/except block where we capture SQLALchemy query failures:
try:
query_result = q.execution_options(timeout=PEGASUS_QUERY_TIMEOUT).all()
except Exception as e:
if sentry_client:
with sentry_client.configure_scope() as scope:
compiled_query = q.statement.compile(
dialect=postgresql.dialect()
)
scope.set_extra("query", str(compiled_query))
scope.set_extra("params", str(compiled_query.params))
raise e
We're working on upgrading the Sentry server, just have a lot of other things to finish up at the moment 馃槄
You only catch and re-raise the error. The error message you see in Sentry does not originate from this piece of code, only the additional data such as query and params does. If you were not to run raise e, I would assume the error would not surface in Sentry.
To be clear, I think somewhere further up the callstack there's code that looks like this:
logger = logging.getLogger("pegasus.services.aquarius.service")
try:
run_query()
except:
logger.error(traceback.format_exc())
This could be hidden in a web framework or something else.
馃う鈥嶁檪 I think I see what you're saying. There is code upstream that does handle exceptions, and runs this: log.error(traceback.format_exc()) inside the exception handler block. I will address there - thank you for helping me figure it out!
Jinx, you hit the nail on the head. Thank you again. I'll close this ticket out.
You can change it to log.error("my code failed", exc_info=True) and it should work!
Most helpful comment
You can change it to
log.error("my code failed", exc_info=True)and it should work!