Skip to content

Commit

Permalink
Tracer now catches errors, closes #2405
Browse files Browse the repository at this point in the history
  • Loading branch information
simonw committed Aug 21, 2024
1 parent 34a6b2a commit 8a63cdc
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 12 deletions.
3 changes: 3 additions & 0 deletions datasette/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,9 @@ def __init__(self, e, sql, params):
self.sql = sql
self.params = params

def __str__(self):
return "QueryInterrupted: {}".format(self.e)


class MultipleValues(Exception):
pass
Expand Down
31 changes: 19 additions & 12 deletions datasette/tracer.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def trace_child_tasks():


@contextmanager
def trace(type, **kwargs):
def trace(trace_type, **kwargs):
assert not TRACE_RESERVED_KEYS.intersection(
kwargs.keys()
), f".trace() keyword parameters cannot include {TRACE_RESERVED_KEYS}"
Expand All @@ -45,17 +45,24 @@ def trace(type, **kwargs):
yield kwargs
return
start = time.perf_counter()
yield kwargs
end = time.perf_counter()
trace_info = {
"type": type,
"start": start,
"end": end,
"duration_ms": (end - start) * 1000,
"traceback": traceback.format_list(traceback.extract_stack(limit=6)[:-3]),
}
trace_info.update(kwargs)
tracer.append(trace_info)
captured_error = None
try:
yield kwargs
except Exception as ex:
captured_error = ex
raise
finally:
end = time.perf_counter()
trace_info = {
"type": trace_type,
"start": start,
"end": end,
"duration_ms": (end - start) * 1000,
"traceback": traceback.format_list(traceback.extract_stack(limit=6)[:-3]),
"error": str(captured_error) if captured_error else None,
}
trace_info.update(kwargs)
tracer.append(trace_info)


@contextmanager
Expand Down
14 changes: 14 additions & 0 deletions tests/test_tracer.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ def test_trace_silently_fails_for_large_page():
assert "_trace" not in big_response.json


def test_trace_query_errors():
with make_app_client(settings={"trace_debug": True}) as client:
response = client.get(
"/fixtures/-/query.json",
params={"_trace": 1, "sql": "select * from non_existent_table"},
)
assert response.status == 400

data = response.json
assert "_trace" in data
trace_info = data["_trace"]
assert trace_info["traces"][-1]["error"] == "no such table: non_existent_table"


def test_trace_parallel_queries():
with make_app_client(settings={"trace_debug": True}) as client:
response = client.get("/parallel-queries?_trace=1")
Expand Down

0 comments on commit 8a63cdc

Please sign in to comment.