Skip to content

fix(data): raise clear error instead of crashing on missing invoice dates - #562

Open
Deez-Automations wants to merge 1 commit into
GenAI-Security-Project:mainfrom
Deez-Automations:fix/payment-null-date-crash-290-291
Open

fix(data): raise clear error instead of crashing on missing invoice dates#562
Deez-Automations wants to merge 1 commit into
GenAI-Security-Project:mainfrom
Deez-Automations:fix/payment-null-date-crash-290-291

Conversation

@Deez-Automations

@Deez-Automations Deez-Automations commented Aug 11, 2026

Copy link
Copy Markdown

Summary

Fixes #290, fixes #291.

Invoice.to_dict() calls .isoformat() directly on invoice_date and due_date with no null guard. Both columns are NOT NULL in the schema, so this is only reachable via corrupted or anomalous data (e.g. a raw SQL write bypassing the ORM constraint) — but when it happens, it crashed with an opaque AttributeError: 'NoneType' object has no attribute 'isoformat' instead of a diagnosable error. Since get_invoice_for_payment (finbot/tools/data/payment.py) calls to_dict() directly, the crash propagated straight into payment processing with no useful message.

Fix

Raises a clear ValueError naming the invoice ID and the specific missing field, instead of crashing with an unhandled AttributeError. Checked that no code anywhere in the codebase catches AttributeError around a to_dict() call, so nothing depends on the old crash type/behavior.

Comparison against another open fix for the same issue

Another contributor has an independent, already-open PR (#293) for the same two issues. Worth comparing openly since both are unmerged:

Both issues' own Expected behavior and Acceptance criteria explicitly say: "ValueError raised with a meaningful message" / "test_pay_field_001 raises ValueError, not AttributeError." This PR does exactly that. PR #293 takes a different approach — it returns None for the missing field instead of raising anything, so the invoice silently serializes with a missing date and flows onward into payment processing rather than surfacing as an error.

That's not necessarily wrong as a general design choice, but it doesn't satisfy what the linked issues themselves ask for, and for a payment pipeline specifically, a loud, diagnosable failure on corrupted data seems safer than a quiet one — silently treating "date field missing" as normal risks masking a real data-integrity problem rather than surfacing it for review. Flagging this for whoever merges, not to relitigate #293, just so the choice between the two approaches is visible.

Test plan

  • New test file tests/unit/data/test_invoice_model.py — reproduces both crashes first (confirmed failing against the unfixed code, exact AttributeError matching both issue reports), then confirms the fix
  • Regression test confirms invoices with valid dates are completely unaffected
  • pytest tests/unit/data/test_invoice_model.py — 3/3 passing

…ates (GenAI-Security-Project#290, GenAI-Security-Project#291)

Invoice.to_dict() called .isoformat() directly on invoice_date and
due_date with no null guard. Both columns are NOT NULL in the schema,
so this only surfaces via corrupted/anomalous data -- but when it does,
it crashed with an opaque AttributeError instead of a diagnosable error,
and the crash propagated straight into payment processing via
get_invoice_for_payment.

Now raises a clear ValueError naming the invoice and the missing field.
Verified no code anywhere catches AttributeError around a to_dict() call,
so nothing depends on the old crash behavior.

Fixes GenAI-Security-Project#290
Fixes GenAI-Security-Project#291
Copilot AI lite review requested due to automatic review settings August 11, 2026 15:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens invoice serialization in the data layer by turning a previously opaque AttributeError (from calling .isoformat() on missing dates) into a clear, diagnosable ValueError, preventing confusing crashes in payment processing paths that rely on Invoice.to_dict().

Changes:

  • Add explicit None guards for invoice_date and due_date in Invoice.to_dict() that raise ValueError with invoice ID + missing field name.
  • Add unit tests covering both missing-date cases and a regression case where both dates are present.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.

File Description
finbot/core/data/models.py Adds explicit validation for missing invoice date fields before serializing to dict.
tests/unit/data/test_invoice_model.py Introduces targeted unit coverage for the new ValueError behavior and a regression test for valid dates.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants