fix: replay errors can be more specific (#31109)

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
This commit is contained in:
Paul D'Ambra
2025-04-11 15:37:51 +02:00
committed by GitHub
parent 0bce776c52
commit 72970818c8
3 changed files with 56 additions and 6 deletions

View File

@@ -91,6 +91,7 @@ Testing
- All new packages and most new significant functionality should come with unit tests
- Significant features should come with integration and/or end-to-end tests
- Analytics-related queries should be covered by snapshot tests for ease of reviewing
- Always consider if you can simplify a test by using the `parameterized.expand` decorator
Unit tests
- A good unit test should:

View File

@@ -8,6 +8,7 @@ from json import JSONDecodeError
from typing import Any, Optional, cast, Literal
import structlog
from clickhouse_driver.errors import ServerException
from posthoganalytics.ai.openai import OpenAI
from urllib.parse import urlparse
@@ -26,6 +27,9 @@ from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.utils.encoders import JSONEncoder
from rest_framework.request import Request
from rest_framework.exceptions import Throttled
from posthog.errors import CHQueryErrorTooManySimultaneousQueries
from ..models.product_intent.product_intent import ProductIntent
import posthog.session_recordings.queries.session_recording_list_from_query
@@ -394,13 +398,30 @@ class SessionRecordingViewSet(TeamAndOrgViewSetMixin, viewsets.GenericViewSet, U
return recording
def list(self, request: request.Request, *args: Any, **kwargs: Any) -> Response:
query = filter_from_params_to_query(request.GET.dict())
user_distinct_id = cast(User, request.user).distinct_id
self._maybe_report_recording_list_filters_changed(request, team=self.team)
return list_recordings_response(
list_recordings_from_query(query, cast(User, request.user), team=self.team),
context=self.get_serializer_context(),
)
try:
query = filter_from_params_to_query(request.GET.dict())
self._maybe_report_recording_list_filters_changed(request, team=self.team)
return list_recordings_response(
list_recordings_from_query(query, cast(User, request.user), team=self.team),
context=self.get_serializer_context(),
)
except CHQueryErrorTooManySimultaneousQueries:
raise Throttled(detail="Too many simultaneous queries. Try again later.")
except (ServerException, Exception) as e:
if isinstance(e, exceptions.ValidationError):
raise
if isinstance(e, ServerException) and "CHQueryErrorTimeoutExceeded" in str(e):
raise Throttled(detail="Query timeout exceeded. Try again later.")
posthoganalytics.capture_exception(
e, distinct_id=user_distinct_id, properties={"replay_feature": "listing_recordings"}
)
return Response({"error": "An internal error has occurred. Please try again later."}, status=500)
@extend_schema(
exclude=True,

View File

@@ -37,6 +37,8 @@ from posthog.test.base import (
flush_persons_and_events,
snapshot_postgres_queries,
)
from clickhouse_driver.errors import ServerException
from posthog.errors import CHQueryErrorTooManySimultaneousQueries
class TestSessionRecordings(APIBaseTest, ClickhouseTestMixin, QueryMatchingTest):
@@ -1343,3 +1345,29 @@ class TestSessionRecordings(APIBaseTest, ClickhouseTestMixin, QueryMatchingTest)
"source": None,
},
)
@parameterized.expand(
[
(
"too_many_queries",
CHQueryErrorTooManySimultaneousQueries("Too many simultaneous queries"),
"Too many simultaneous queries. Try again later.",
),
(
"timeout_exceeded",
ServerException("CHQueryErrorTimeoutExceeded"),
"Query timeout exceeded. Try again later.",
),
]
)
@patch("posthog.session_recordings.queries.session_recording_list_from_query.SessionRecordingListFromQuery.run")
def test_session_recordings_query_errors(self, name, exception, expected_message, mock_run):
mock_run.side_effect = exception
response = self.client.get(f"/api/projects/{self.team.id}/session_recordings")
assert response.status_code == status.HTTP_429_TOO_MANY_REQUESTS
assert response.json() == {
"attr": None,
"code": "throttled",
"detail": expected_message,
"type": "throttled_error",
}