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
11 changes: 7 additions & 4 deletions backend/api/v1/endpoints/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,14 @@ def trigger_sync(
type_override = next(
(t for g, t, _ in SYNC_GROUPS if g == group), None
)
count = spacetrack_service.sync_group(db, group, type_override, limit=limit)
status = spacetrack_service.sync_group(db, group, type_override, limit=limit)
return APIResponse(
success=True,
message=f"Synced group '{group}': {count} objects upserted",
data={"group": group, "upserted": count},
success=status["failed"] == 0,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 success=True when the DB is unreachable

When sync_group cannot reach MongoDB it returns {"failed": 0, "upserted": 0, "errors": ["db_unreachable"]}. The condition status["failed"] == 0 evaluates to True because failed is 0, so the endpoint responds with {"success": true} despite the sync never running. Any monitoring that relies on the success flag to detect infrastructure issues will silently miss DB connectivity failures.

Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/api/v1/endpoints/catalog.py
Line: 163

Comment:
**`success=True` when the DB is unreachable**

When `sync_group` cannot reach MongoDB it returns `{"failed": 0, "upserted": 0, "errors": ["db_unreachable"]}`. The condition `status["failed"] == 0` evaluates to `True` because `failed` is `0`, so the endpoint responds with `{"success": true}` despite the sync never running. Any monitoring that relies on the `success` flag to detect infrastructure issues will silently miss DB connectivity failures.

How can I resolve this? If you propose a fix, please make it concise.

message=(
f"Synced group '{group}': {status['upserted']} upserted, "
f"{status['failed']} failed"
),
data=status,
Comment on lines +161 to +168

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

success ignores status["errors"] — silently reports success on total failure.

sync_group's early-return paths (db_unreachable, no_records) set failed: 0 while populating errors. Since success here is computed as status["failed"] == 0, a DB-unreachable or zero-records sync reports success=True with a "0 upserted, 0 failed" message — exactly the silent-failure scenario issue #10 asks to prevent.

🐛 Proposed fix
         status = spacetrack_service.sync_group(db, group, type_override, limit=limit)
         return APIResponse(
-            success=status["failed"] == 0,
+            success=status["failed"] == 0 and not status["errors"],
             message=(
                 f"Synced group '{group}': {status['upserted']} upserted, "
-                f"{status['failed']} failed"
+                f"{status['failed']} failed"
+                + (f" — errors: {status['errors']}" if status["errors"] else "")
             ),
             data=status,
         )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
status = spacetrack_service.sync_group(db, group, type_override, limit=limit)
return APIResponse(
success=True,
message=f"Synced group '{group}': {count} objects upserted",
data={"group": group, "upserted": count},
success=status["failed"] == 0,
message=(
f"Synced group '{group}': {status['upserted']} upserted, "
f"{status['failed']} failed"
),
data=status,
status = spacetrack_service.sync_group(db, group, type_override, limit=limit)
return APIResponse(
success=status["failed"] == 0 and not status["errors"],
message=(
f"Synced group '{group}': {status['upserted']} upserted, "
f"{status['failed']} failed"
(f" — errors: {status['errors']}" if status["errors"] else "")
),
data=status,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/api/v1/endpoints/catalog.py` around lines 161 - 168, Update the
success calculation in the catalog endpoint around sync_group to require both
zero failed records and no entries in status["errors"]. Preserve the existing
response message and data payload while ensuring early-return errors such as
db_unreachable and no_records cannot report success.

)

def _bg_sync():
Expand Down
14 changes: 11 additions & 3 deletions backend/app/tasks/celery_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@ def sync_spacetrack_data():
logger.info("Executing periodic catalog synchronization...")
db = SessionLocal()
try:
spacetrack_service.sync_objects(db)
logger.info("Space-Track sync succeeded.")
status = spacetrack_service.sync_all_groups(db, limit_per_group=500)
if status["total_failed"] > 0:
logger.warning(
f"Space-Track sync completed with issues — "
f"upserted={status['total_upserted']}, failed={status['total_failed']}."
)
else:
logger.info(
f"Space-Track sync succeeded — upserted={status['total_upserted']}."
)
Comment on lines +15 to +24

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

total_failed under-reports failures for the same reason as catalog.py.

sync_all_groups sums each group's failed, but sync_group's db_unreachable/no_records early returns have failed: 0 with only errors populated. A fully-failed sync (e.g., Mongo unreachable for every group) logs at info level ("Space-Track sync succeeded") instead of warning, masking the failure in logs that this PR is meant to make visible.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/tasks/celery_tasks.py` around lines 15 - 24, The Celery task’s
success check relies on `status["total_failed"]`, but `sync_all_groups` does not
count failures represented only in each group’s `errors`. Update `sync_group`
and the aggregation in `sync_all_groups` so `db_unreachable`/`no_records` early
returns contribute to the failure total, ensuring fully failed syncs reach the
warning branch in the task logger.

except Exception as e:
logger.error(f"Space-Track sync task failed: {e}")
logger.error(f"Space-Track sync task failed: {e}", exc_info=True)
finally:
db.close()

Expand Down
Loading