|
1 | 1 | import logging |
| 2 | +from datetime import datetime |
2 | 3 | from typing import Any |
3 | 4 |
|
4 | 5 | import sentry_sdk |
@@ -193,15 +194,39 @@ def post(self, request: Request, project: Project, replay_id: str) -> Response: |
193 | 194 | status=404, |
194 | 195 | ) |
195 | 196 |
|
196 | | - # Extract start and end times from the replay (pass None if missing). |
| 197 | + # Extract start and end times from the replay (pass None if missing or invalid). |
197 | 198 | replay = process_raw_response(snuba_response, fields=[])[0] |
198 | 199 |
|
| 200 | + def validate_iso_timestamp(timestamp: str | None) -> str | None: |
| 201 | + """Validate that timestamp is a valid ISO format string, return None if invalid.""" |
| 202 | + if not timestamp: |
| 203 | + return None |
| 204 | + try: |
| 205 | + datetime.fromisoformat(timestamp) |
| 206 | + return timestamp |
| 207 | + except (ValueError, TypeError): |
| 208 | + return None |
| 209 | + |
| 210 | + replay_start = validate_iso_timestamp(replay.get("started_at")) |
| 211 | + replay_end = validate_iso_timestamp(replay.get("finished_at")) |
| 212 | + |
| 213 | + if not replay_start or not replay_end: |
| 214 | + logger.warning( |
| 215 | + "Replay start or end time missing or invalid.", |
| 216 | + extra={ |
| 217 | + "started_at": replay.get("started_at"), |
| 218 | + "finished_at": replay.get("finished_at"), |
| 219 | + "replay_id": replay_id, |
| 220 | + "organization_id": project.organization.id, |
| 221 | + }, |
| 222 | + ) |
| 223 | + |
199 | 224 | return self.make_seer_request( |
200 | 225 | SEER_START_TASK_ENDPOINT_PATH, |
201 | 226 | { |
202 | 227 | "replay_id": replay_id, |
203 | | - "replay_start": replay.get("started_at"), |
204 | | - "replay_end": replay.get("finished_at"), |
| 228 | + "replay_start": replay_start, |
| 229 | + "replay_end": replay_end, |
205 | 230 | "num_segments": num_segments, |
206 | 231 | "organization_id": project.organization.id, |
207 | 232 | "project_id": project.id, |
|
0 commit comments