Merge pull request #82 from christianlouis/copilot/fix-datetime-subtraction-error

Fix offset-naive/offset-aware datetime subtraction in process_mail_account
This commit is contained in:
Christian Krakau-Louis
2026-03-26 14:05:38 +01:00
committed by GitHub
2 changed files with 14 additions and 2 deletions
+3
View File
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Fixed
- Fixed `TypeError: can't subtract offset-naive and offset-aware datetimes` in `process_mail_account` task when computing `duration_seconds`. After a database refresh, `started_at` may be returned as a naive datetime; it is now normalized to UTC before subtraction.
### Security
- Upgraded `python-jose` from 3.3.0 to 3.5.0 to fix CVE: algorithm confusion vulnerability with OpenSSH ECDSA keys (affected versions < 3.4.0).
- Upgraded `python-jose[cryptography]` from `3.3.0` to `3.4.0` to fix an algorithm-confusion vulnerability with OpenSSH ECDSA keys (CVE affects all versions < 3.4.0).
+11 -2
View File
@@ -29,6 +29,13 @@ from sqlalchemy import select, delete
logger = logging.getLogger(__name__)
def _as_utc(dt: datetime) -> datetime:
"""Return *dt* with UTC tzinfo, attaching it if the datetime is naive."""
if dt.tzinfo is None:
return dt.replace(tzinfo=timezone.utc)
return dt
class AsyncTask(Task):
"""Base task class that handles async operations"""
@@ -249,7 +256,9 @@ async def process_mail_account(account_id: int):
run.emails_forwarded = emails_forwarded # type: ignore[assignment]
run.emails_failed = emails_failed # type: ignore[assignment]
run.completed_at = datetime.now(timezone.utc) # type: ignore[assignment]
run.duration_seconds = (run.completed_at - run.started_at).total_seconds()
run.duration_seconds = (
run.completed_at - _as_utc(run.started_at)
).total_seconds()
run.status = "completed" if emails_failed == 0 else "partial_failure" # type: ignore[assignment]
# Update account
@@ -281,7 +290,7 @@ async def process_mail_account(account_id: int):
run.error_message = str(e) # type: ignore[assignment]
run.completed_at = datetime.now(timezone.utc) # type: ignore[assignment]
run.duration_seconds = (
run.completed_at - run.started_at
run.completed_at - _as_utc(run.started_at)
).total_seconds()
# Update account error status