Skip to content

fix: CodeRabbit compliance — narrow exceptions, add compatible_versions#6

Open
5ymb01 wants to merge 3 commits intoChuckBuilds:masterfrom
5ymb01:fix/coderabbit-compliance
Open

fix: CodeRabbit compliance — narrow exceptions, add compatible_versions#6
5ymb01 wants to merge 3 commits intoChuckBuilds:masterfrom
5ymb01:fix/coderabbit-compliance

Conversation

@5ymb01
Copy link

@5ymb01 5ymb01 commented Mar 8, 2026

Description

Addresses all CodeRabbit code quality findings across the stocks plugin codebase — narrows broad exception handlers, adds type-safe config parsing, removes dead code, and adds missing manifest fields.

Type of Change

  • Bug fix (non-breaking change)
  • New feature (non-breaking change)
  • Breaking change
  • Documentation update
  • Performance improvement
  • Refactoring

Changes

File Changes
manifest.json Add compatible_versions, fix min_ledmatrix_version
manager.py Narrow 3 broad excepts to specific types
config_manager.py Add _to_float()/_to_color() helpers, narrow 4 broad excepts
data_fetcher.py Narrow 4 broad excepts, remove dead _extract_json_from_html()
chart_renderer.py Narrow 6 broad excepts to specific types
display_renderer.py Narrow 3 broad excepts, add debug logging to silent catches

CodeRabbit Compliance

  • Zero except Exception blocks remaining
  • Zero import traceback statements
  • Zero traceback.format_exc() calls
  • All except blocks log errors (no silent catches)
  • compatible_versions in manifest
  • Type-safe config parsing with fallback defaults

Testing

  • Tested on Raspberry Pi hardware
  • Verified display rendering works correctly
  • Checked API integration functionality
  • Tested error handling scenarios

Test Plan

  • Run existing test suite — verify no regressions
  • Verify stock data fetching works with narrowed exception types
  • Verify chart rendering handles edge cases (zero price range, missing data)
  • Check config loading with invalid values falls back to defaults

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Comments added for complex logic
  • No hardcoded values or API keys
  • Error handling implemented
  • Logging added where appropriate

Author: @5ymb01
AI Assistant: Claude Opus 4.6 (Anthropic)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Support for dual-format configuration parsing with richer color customization.
    • Added manifest compatibility property for version tracking.
  • Bug Fixes

    • Improved error handling across rendering, data fetching, display, and manager components for more graceful degradation.
    • Stronger configuration validation and type coercion with safe fallbacks.
    • More robust font-loading error reporting and fallback behavior.

5ymb01 and others added 2 commits March 7, 2026 22:33
config_manager.py:
- Add _to_float() and _to_color() type coercion helpers to prevent
  TypeError/ValueError from string or malformed config values
- Apply _to_float() to scroll_speed, scroll_delay, min_duration,
  max_duration, duration_buffer in both new-format and old-format paths
- Apply _to_color() to all 6 color config reads (stock + crypto)
- Narrow broad `except Exception` in _load_config, reload_config,
  validate_config to specific types (KeyError, TypeError, ValueError,
  AttributeError)
- Add return type hints to __init__, _init_attributes

data_fetcher.py:
- Remove dead _extract_json_from_html() method (never called)
- Replace stale web_interface_v2 try/except import with no-op stub
- Remove unused `import re`
- Add return type hint to cleanup()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nup traceback

- Narrow 18 `except Exception` blocks to specific types across all .py files:
  - data_fetcher.py: 4 blocks → (requests.RequestException, ValueError, KeyError, TypeError) etc.
  - manager.py: 5 blocks → specific types + replace import traceback with logger.exception() (TRY401)
  - chart_renderer.py: 6 blocks → (AttributeError, TypeError, ValueError, ZeroDivisionError, OSError)
  - display_renderer.py: 3 blocks → (OSError, ValueError, TypeError, AttributeError)
- Add `compatible_versions` to manifest.json (schema-required field)
- Replace `import traceback` + manual format with `self.logger.exception()` (Ruff TRY401)

Co-authored-by: 5ymb01 <5ymb01@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Mar 8, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2f28b3ed-b42c-4f3e-8bc9-106ed1aaa291

📥 Commits

Reviewing files that changed from the base of the PR and between f0343c3 and 0531b5c.

📒 Files selected for processing (1)
  • manager.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • manager.py

📝 Walkthrough

Walkthrough

Refactors exception handling across multiple modules to narrower, explicit exception tuples; adds safe type-coercion helpers and restructuring to configuration loading; initializes an HTTP session and optional background service in the data fetcher; and adds a compatible_versions entry to manifest.json.

Changes

Cohort / File(s) Summary
Chart & Display Rendering
chart_renderer.py, display_renderer.py
Replaced broad except Exception blocks with explicit exception tuples (AttributeError, TypeError, ValueError, ZeroDivisionError, OSError). Updated font-loading error handling/logging to catch specific exceptions and include more detail.
Manager Logic / Error Logging
manager.py
Narrowed catch blocks to specific exceptions (AttributeError, ValueError, TypeError, RuntimeError, OSError) and replaced manual traceback handling with logger.exception.
Configuration Management
config_manager.py
Added StockConfigManager._to_float and ._to_color helpers. Refactored loading to support nested and legacy formats, applied coercion helpers for numeric/color values, added initialization helpers (_init_attributes, _set_defaults), and widened validation/error handling.
Data Fetching & Services
data_fetcher.py
Added module-level increment_api_counter no-op, introduced _init_http_session (retries/headers) and _init_background_service, tightened exception handling in fetch flows (requests.RequestException, ValueError, KeyError, TypeError, AttributeError, RuntimeError, TimeoutError). Updated cleanup(self) signature to return None.
Manifest
manifest.json
Added compatible_versions property with value [\">=2.0.0\"]; preserved existing max_ledmatrix_version.

Sequence Diagram(s)

sequenceDiagram
    participant App
    participant Fetcher as StockDataFetcher
    participant BG as BackgroundService (optional)
    participant API as External API

    App->>Fetcher: fetch_all_data()
    alt background service enabled
        Fetcher->>BG: request_data()
        BG->>API: fetch remote data
        API-->>BG: data response
        BG-->>Fetcher: data
    else direct fetch
        Fetcher->>API: HTTP request (session with retries)
        API-->>Fetcher: data response
    end
    Fetcher->>Fetcher: parse & validate (specific exception handling)
    Fetcher-->>App: return data / None on error
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: narrowing exception handlers and adding the compatible_versions field to address CodeRabbit compliance findings.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@5ymb01
Copy link
Author

5ymb01 commented Mar 8, 2026

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Mar 8, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@5ymb01
Copy link
Author

5ymb01 commented Mar 8, 2026

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Mar 8, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
display_renderer.py (2)

156-158: Consider using logger.exception() for better debugging context.

Static analysis suggests replacing logger.error() with logger.exception() when logging inside exception handlers. This automatically includes the stack trace, which aids debugging.

♻️ Proposed fix
         except (OSError, ValueError, TypeError, AttributeError) as e:
-            self.logger.error("Error loading font %s: %s, using default", font_name, e)
+            self.logger.exception("Error loading font %s, using default", font_name)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@display_renderer.py` around lines 156 - 158, Replace the call to
self.logger.error inside the except block that catches (OSError, ValueError,
TypeError, AttributeError) when loading fonts with self.logger.exception so the
stack trace is included; locate the except that logs "Error loading font %s: %s,
using default" (the one that captures variable e) and call self.logger.exception
with a concise message like "Error loading font %s, using default" and the
font_name so the exception and traceback are automatically recorded.

167-169: Consider using logger.exception() for consistency.

Same as above—using logger.exception() provides automatic stack traces in exception handlers.

♻️ Proposed fix
         except (OSError, ValueError, TypeError) as e:
-            self.logger.error("Error loading default font: %s", e)
+            self.logger.exception("Error loading default font")
             return ImageFont.load_default()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@display_renderer.py` around lines 167 - 169, The except block that currently
calls self.logger.error("Error loading default font: %s", e) in the handler for
except (OSError, ValueError, TypeError) as e should use
self.logger.exception(...) to capture the full stack trace for consistency;
replace the self.logger.error call with self.logger.exception("Error loading
default font") while keeping the return ImageFont.load_default() behavior
unchanged so callers still get a fallback font.
data_fetcher.py (1)

101-102: Consider using logger.exception() for stack traces.

Static analysis suggests using logger.exception() instead of logger.error() in exception handlers. However, for per-symbol errors in a loop, you may prefer the current approach to avoid verbose logs. If you want stack traces for debugging, consider:

♻️ Optional: Use logger.exception for debugging
             except (requests.RequestException, ValueError, KeyError, TypeError) as e:
-                self.logger.error("Error fetching stock data for %s: %s", symbol, e)
+                self.logger.exception("Error fetching stock data for %s", symbol)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@data_fetcher.py` around lines 101 - 102, The except block catching
(requests.RequestException, ValueError, KeyError, TypeError) currently calls
self.logger.error("Error fetching stock data for %s: %s", symbol, e); replace
that with self.logger.exception("Error fetching stock data for %s", symbol) (or
call self.logger.error(..., exc_info=True)) so the stack trace is recorded; if
you want to avoid verbose traces for normal runs, gate the use of
logger.exception/ exc_info=True behind a debug/config flag (use the same except
block surrounding the symbol fetch logic in data_fetcher.py where
self.logger.error is used).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@manager.py`:
- Around line 195-197: The except block declares an unused exception variable
`e`; update the exception handler for the block around self.logger.exception and
self.scroll_helper.clear_cache to drop the variable and use a bare except clause
with exception binding omitted (i.e., change "except (AttributeError,
ValueError, TypeError, OSError) as e:" to "except (AttributeError, ValueError,
TypeError, OSError):"), leaving the calls to self.logger.exception("Error
creating scrolling display") and self.scroll_helper.clear_cache() unchanged.
- Around line 104-105: The except block currently binds the exception to a
variable named e but never uses it; update the except clause in the method
containing the line with logger.exception("Error updating stock/crypto data") to
remove the unused variable (change "except (ValueError, AttributeError,
RuntimeError, TypeError) as e:" to "except (ValueError, AttributeError,
RuntimeError, TypeError):") so logger.exception(...) continues to record the
exception and stack trace without an unused variable.

---

Nitpick comments:
In `@data_fetcher.py`:
- Around line 101-102: The except block catching (requests.RequestException,
ValueError, KeyError, TypeError) currently calls self.logger.error("Error
fetching stock data for %s: %s", symbol, e); replace that with
self.logger.exception("Error fetching stock data for %s", symbol) (or call
self.logger.error(..., exc_info=True)) so the stack trace is recorded; if you
want to avoid verbose traces for normal runs, gate the use of logger.exception/
exc_info=True behind a debug/config flag (use the same except block surrounding
the symbol fetch logic in data_fetcher.py where self.logger.error is used).

In `@display_renderer.py`:
- Around line 156-158: Replace the call to self.logger.error inside the except
block that catches (OSError, ValueError, TypeError, AttributeError) when loading
fonts with self.logger.exception so the stack trace is included; locate the
except that logs "Error loading font %s: %s, using default" (the one that
captures variable e) and call self.logger.exception with a concise message like
"Error loading font %s, using default" and the font_name so the exception and
traceback are automatically recorded.
- Around line 167-169: The except block that currently calls
self.logger.error("Error loading default font: %s", e) in the handler for except
(OSError, ValueError, TypeError) as e should use self.logger.exception(...) to
capture the full stack trace for consistency; replace the self.logger.error call
with self.logger.exception("Error loading default font") while keeping the
return ImageFont.load_default() behavior unchanged so callers still get a
fallback font.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8a36968a-bdb1-4712-9b29-52d05d96534e

📥 Commits

Reviewing files that changed from the base of the PR and between 7be294c and f0343c3.

📒 Files selected for processing (6)
  • chart_renderer.py
  • config_manager.py
  • data_fetcher.py
  • display_renderer.py
  • manager.py
  • manifest.json

logger.exception() automatically captures exception info, so the
bound variable 'e' is unused. Removes Ruff F841 warnings.

Co-Authored-By: 5ymb01 <5ymb01@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

1 participant