calculate_priority: resolve non-finite prices to 0 instead of crashing the monitor #25

Merged
dsql merged 1 commits from development into main 2026-10-08 22:48:57 +00:00
Owner

tpv-academysports crash-looped on 2026-10-08 (6x OverflowError: cannot convert float infinity to integer in calculate_priority, then docker on-failure:5 gave up). A non-finite retailer price (float() accepts "Infinity") escaped run_monitor_cycle and killed the process. calculate_priority now returns 0 for non-finite prices and for an overflowing ratio; tests fail before / pass after (tests/test_alert_priority.py: 10 passed). Every tpv monitor pulls this lib unpinned from main, so they all pick it up on their next image build.

tpv-academysports crash-looped on 2026-10-08 (6x `OverflowError: cannot convert float infinity to integer` in `calculate_priority`, then docker on-failure:5 gave up). A non-finite retailer price (float() accepts "Infinity") escaped run_monitor_cycle and killed the process. calculate_priority now returns 0 for non-finite prices and for an overflowing ratio; tests fail before / pass after (tests/test_alert_priority.py: 10 passed). Every tpv monitor pulls this lib unpinned from main, so they all pick it up on their next image build.
dsql added 1 commit 2026-10-08 22:48:56 +00:00
tpv-academysports died on 2026-10-08 06:27 UTC and stayed down: six
identical crashes in 8 minutes (each ~2 min after start), then docker's
on-failure:5 gave up. Every one was

    database.py, in calculate_priority
        percentage = int(((original_price - current_price) / original_price) * 100)
    OverflowError: cannot convert float infinity to integer

A monitor builds prices with float() on the retailer's raw field, and
float() accepts "Infinity" / "1e999", so a non-finite price reaches here.
The `not original_price` guard catches None and 0, not inf or nan, and the
exception escapes add_products_to_database -> run_monitor_cycle and kills
the whole process -- one bad product takes the monitor down, and it
crashes again on every restart while that product is listed. Every
monitor that uses this lib has the same exposure.

calculate_priority now returns 0 (the existing "broken prices" bucket)
for a non-finite current/original price, and for a finite pair whose
ratio still overflows (a subnormal original price). Tests cover both;
they fail on the old code (OverflowError, plus ValueError for nan) and
pass now (tests/test_alert_priority.py: 10 passed).

Not changed: the monitor-side float() parsing, which could reject these
prices before they are stored -- worth a look by the monitor owners.

Co-Authored-By: Claude Code Opus 5.5 (ansible-ops, auto-repair) <noreply@anthropic.com>
Signed-off-by: disqualifier <dev@disqualifier.me>
dsql merged commit 7d514a5401 into main 2026-10-08 22:48:57 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: pl_devs/monitor-shared-utils#25