Skip to content

Harden recorder statistics against bad integration data#165221

Draft
gronke wants to merge 3 commits intohome-assistant:devfrom
gronke:harden-recorder-statistics
Draft

Harden recorder statistics against bad integration data#165221
gronke wants to merge 3 commits intohome-assistant:devfrom
gronke:harden-recorder-statistics

Conversation

@gronke
Copy link

@gronke gronke commented Mar 9, 2026

Proposed change

A misbehaving integration (e.g. Victron passing a Python object as unit_of_measurement instead of a string, see sfstar/hass-victron#424) can crash the entire statistics pipeline, killing statistics collection for all integrations — not just the offending one. The user sees a blank statistics dashboard with no indication of which integration caused it.

This PR adds three layers of error isolation:

  1. Per-platform try/except around compile_statistics callbacks — a crashing platform no longer blocks other platforms.
  2. Per-entity try/except in the statistics insertion loop — a bad entity no longer prevents other entities from being recorded.
  3. Type validation for unit_of_measurement in the sensor recorder — a non-string value is caught early with a clear error log naming the offending entity and integration, instead of propagating into SQLite and crashing there.

All error paths produce clear log messages identifying the offending entity or platform domain.

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Checklist

  • I understand the code I am submitting and can explain how it works.
  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.
  • Any generated code has been carefully reviewed for correctness and compliance with project standards.

To help with the load of incoming pull requests:

Copilot AI review requested due to automatic review settings March 9, 2026 17:38
@gronke gronke requested a review from a team as a code owner March 9, 2026 17:38
Copy link

@home-assistant home-assistant bot left a comment

Choose a reason for hiding this comment

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

Hi @gronke

It seems you haven't yet signed a CLA. Please do so here.

Once you do that we will be able to review and accept this pull request.

Thanks!

@home-assistant home-assistant bot marked this pull request as draft March 9, 2026 17:38
@home-assistant
Copy link

home-assistant bot commented Mar 9, 2026

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍

Learn more about our pull request process.

@home-assistant
Copy link

home-assistant bot commented Mar 9, 2026

Hey there @home-assistant/core, mind taking a look at this pull request as it has been labeled with an integration (sensor) you are listed as a code owner for? Thanks!

Code owner commands

Code owners of sensor can trigger bot actions by commenting:

  • @home-assistant close Closes the pull request.
  • @home-assistant rename Awesome new title Renames the pull request.
  • @home-assistant reopen Reopen the pull request.
  • @home-assistant unassign sensor Removes the current integration label and assignees on the pull request, add the integration domain after the command.
  • @home-assistant add-label needs-more-information Add a label (needs-more-information, problem in dependency, problem in custom component, problem in config, problem in device, feature-request) to the pull request.
  • @home-assistant remove-label needs-more-information Remove a label (needs-more-information, problem in dependency, problem in custom component, problem in config, problem in device, feature-request) on the pull request.

@home-assistant
Copy link

home-assistant bot commented Mar 9, 2026

Hey there @home-assistant/core, mind taking a look at this pull request as it has been labeled with an integration (recorder) you are listed as a code owner for? Thanks!

Code owner commands

Code owners of recorder can trigger bot actions by commenting:

  • @home-assistant close Closes the pull request.
  • @home-assistant rename Awesome new title Renames the pull request.
  • @home-assistant reopen Reopen the pull request.
  • @home-assistant unassign recorder Removes the current integration label and assignees on the pull request, add the integration domain after the command.
  • @home-assistant add-label needs-more-information Add a label (needs-more-information, problem in dependency, problem in custom component, problem in config, problem in device, feature-request) to the pull request.
  • @home-assistant remove-label needs-more-information Remove a label (needs-more-information, problem in dependency, problem in custom component, problem in config, problem in device, feature-request) on the pull request.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Hardens the recorder statistics compilation pipeline so that misbehaving integrations/entities don’t crash statistics collection for unrelated platforms.

Changes:

  • Add per-platform exception isolation around recorder compile_statistics callbacks.
  • Add per-entity exception isolation around statistics metadata update/insertion.
  • Validate unit_of_measurement type in sensor statistics normalization and skip offending entities with a clear log message.
  • Add tests covering bad platform callbacks, bad entity insertion, and non-string sensor units.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
homeassistant/components/recorder/statistics.py Adds per-platform and per-entity exception isolation while compiling/inserting statistics.
homeassistant/components/sensor/recorder.py Adds type validation for unit_of_measurement before statistics unit normalization proceeds.
tests/components/recorder/test_statistics.py Adds tests ensuring a crashing platform/entity doesn’t block other platforms/entities.
tests/components/sensor/test_recorder.py Updates expectation for platform-level error logging and adds test for non-string unit handling.

You can also share your feedback on Copilot code review. Take the survey.

@karwosts
Copy link
Member

karwosts commented Mar 9, 2026

Likely fixes #158494

Actually I misremembered, that one was an issue with type of state_class, not unit_of_measurement. Maybe this addresses that, not sure.

Isolate per-platform and per-entity errors in the statistics compilation
pipeline so a single misbehaving integration (e.g. non-string
unit_of_measurement) no longer crashes all statistics collection.

- Wrap platform compile_statistics callbacks in try/except
- Wrap per-entity statistics insertion in try/except
- Validate unit_of_measurement type in sensor recorder before it enters metadata
- Add tests verifying error isolation (pass with fix, fail without)
- Update test assertion to match new error handling behavior
@gronke gronke force-pushed the harden-recorder-statistics branch from 7dd542d to 7be11a0 Compare March 9, 2026 18:18
gronke added 2 commits March 9, 2026 22:01
Proves our per-platform error isolation catches the TypeError from
unhashable state_class values, preventing it from crashing the
entire statistics pipeline.
Wrap update_statistics_issues callbacks in try/except in both
_compile_statistics (minute=50 path) and the standalone function.
Add tests for the new error isolation and for home-assistant#158494 at minute=50.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants