Skip to content

fix(report): correctly parse millisecond Unix timestamps in report expiration checks#652

Merged
drazisil-codecov merged 3 commits intomainfrom
joebecher/fix-millisecond-timestamp-parsing
Jan 22, 2026
Merged

fix(report): correctly parse millisecond Unix timestamps in report expiration checks#652
drazisil-codecov merged 3 commits intomainfrom
joebecher/fix-millisecond-timestamp-parsing

Conversation

@drazisil-codecov
Copy link
Contributor

@drazisil-codecov drazisil-codecov commented Jan 14, 2026

Summary

Coverage report processors (Jacoco, Cobertura, Clover) were incorrectly flagging valid reports as expired when timestamps were in milliseconds (13+ digits) instead of seconds (10 digits).

The Problem

The timestring.Date() library expects seconds-based Unix timestamps, but some tools emit millisecond timestamps (13 digits like 1768258631332). When passed directly to Date(), these are parsed incorrectly, causing valid reports to be flagged as expired.

Example from Sentry:

  • Timestamp: 1768258631332 (milliseconds)
  • Actual date: 2026-01-12 17:57:11 (only 2 days old - NOT expired!)
  • Date() interprets it as: Year 58003 (overflow/incorrect)
  • Result: ReportExpiredException even though the report is valid

Impact

This was causing ~1.5M false errors/month in Sentry:

  • WORKER-Q95 (Clover): ~124K events
  • WORKER-Q96 (Jacoco): ~1.06M events
  • WORKER-Q97 (Cobertura): ~308K events

Solution

Added normalize_timestamp() helper that detects millisecond timestamps (13+ digits) and converts them to seconds before passing to timestring.Date().

Changes

  1. base.py: Added normalize_timestamp() helper function
  2. jacoco.py: Apply normalization before Date comparison
  3. cobertura.py: Apply normalization before Date comparison
  4. clover.py: Apply normalization before Date comparison

Testing

  • Added comprehensive unit tests for normalize_timestamp() helper
  • Added millisecond timestamp test cases to existing expiration tests
  • Added explicit "not expired" tests with recent millisecond timestamps

Fixes WORKER-Q95, WORKER-Q96, WORKER-Q97


Note

Ensures coverage report expiration checks work with millisecond Unix timestamps by normalizing to seconds before timestring.Date() parsing.

  • Adds normalize_timestamp() in languages/base.py to convert 13+ digit Unix timestamps to seconds
  • Applies normalization in clover.py, cobertura.py, and jacoco.py; exception messages now include the original timestamp
  • Clover retains DD-MM-YYYY to MM-DD-YYYY swap prior to normalization
  • Adds unit tests: new tests for normalize_timestamp() and updated expiration tests for all three processors, including recent millisecond "not expired" cases

Written by Cursor Bugbot for commit e5eb9c4. This will update automatically on new commits. Configure here.

@drazisil-codecov drazisil-codecov requested a review from a team as a code owner January 14, 2026 14:52
@drazisil-codecov drazisil-codecov force-pushed the joebecher/fix-millisecond-timestamp-parsing branch from 30405a5 to 14f8fe8 Compare January 14, 2026 14:59
@drazisil-codecov drazisil-codecov requested review from a team and removed request for a team January 14, 2026 14:59
@drazisil-codecov drazisil-codecov force-pushed the joebecher/fix-millisecond-timestamp-parsing branch from 14f8fe8 to ee813ba Compare January 14, 2026 15:01
…piration checks

Coverage report processors (Jacoco, Cobertura, Clover) were incorrectly
flagging valid reports as expired when timestamps were in milliseconds
(13+ digits) instead of seconds (10 digits).

The timestring.Date() library expects seconds-based Unix timestamps, but
some tools (like certain Clover implementations) emit millisecond timestamps.
This caused ~1.5M false 'ReportExpiredException' errors in Sentry.

Changes:
- Add normalize_timestamp() helper to convert millisecond timestamps to seconds
- Apply normalization in jacoco.py, cobertura.py, and clover.py
- Add comprehensive unit tests for the helper and timestamp handling

Fixes WORKER-Q95, WORKER-Q96, WORKER-Q97
@drazisil-codecov drazisil-codecov force-pushed the joebecher/fix-millisecond-timestamp-parsing branch from ee813ba to 33ec955 Compare January 14, 2026 15:02
@sentry
Copy link

sentry bot commented Jan 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.35%. Comparing base (5dd9a49) to head (e5eb9c4).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #652   +/-   ##
=======================================
  Coverage   93.35%   93.35%           
=======================================
  Files        1292     1292           
  Lines       47126    47138   +12     
  Branches     1567     1567           
=======================================
+ Hits        43994    44006   +12     
  Misses       2823     2823           
  Partials      309      309           
Flag Coverage Δ
workerintegration 59.10% <14.81%> (-0.04%) ⬇️
workerunit 91.27% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@codecov-notifications
Copy link

codecov-notifications bot commented Jan 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Addresses Bugbot feedback: normalize_timestamp() can return None
for empty strings, and Date(None) raises TypeError instead of
TimestringInvalid. Now we check if timestamp is truthy before
attempting to parse it, consistent with clover.py and jacoco.py.
Addresses review feedback - the docstring in normalize_timestamp()
already explains the millisecond handling, so inline comments were
repetitive.
@drazisil-codecov
Copy link
Contributor Author

Addressed the review feedback:

Re: Missing truthy check (cursor[bot])
This was already fixed in the second commit - the code now checks if timestamp: before calling Date().

Re: Redundant comments
Removed the redundant inline comments. The docstring in normalize_timestamp() already explains the millisecond handling, so the inline comments were repetitive. Kept only the one in clover.py that explains the DD-MM-YYYY swap since that's a separate concern.

@drazisil-codecov drazisil-codecov added this pull request to the merge queue Jan 22, 2026
Merged via the queue into main with commit 57686c4 Jan 22, 2026
83 of 88 checks passed
@drazisil-codecov drazisil-codecov deleted the joebecher/fix-millisecond-timestamp-parsing branch January 22, 2026 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants