Skip to content

fix: guard moonraker None deref in in_print_reactor_timer#703

Open
SAY-5 wants to merge 1 commit into
AFCProject:DEVfrom
SAY-5:fix/moonraker-none-check-702
Open

fix: guard moonraker None deref in in_print_reactor_timer#703
SAY-5 wants to merge 1 commit into
AFCProject:DEVfrom
SAY-5:fix/moonraker-none-check-702

Conversation

@SAY-5
Copy link
Copy Markdown

@SAY-5 SAY-5 commented May 5, 2026

Major Changes in this PR

Fixes #702. If PREP is not run, self.moonraker is None. The reactor timer in_print_reactor_timer then calls self.moonraker.get_file_filament_change_count(print_filename) on NoneType, raising AttributeError and crashing klipper:

File "/home/Slay/klipper/klippy/extras/AFC.py", line 499, in in_print_reactor_timer
    self.number_of_toolchanges  = self.moonraker.get_file_filament_change_count(print_filename)
AttributeError: 'NoneType' object has no attribute 'get_file_filament_change_count'

Adds a self.moonraker is not None check alongside the existing in_print check, matching the same guard pattern already in use for the td1_present property.

Notes to Code Reviewers

The fix is a single conjunct added to the if in_print: condition at extras/AFC.py:552 (DEV branch). Same pattern as td1_present (around line 516) which already gates moonraker access on self.moonraker is not None.

How the changes in this PR are tested

Three unit tests added to tests/test_AFC.py (TestInPrintReactorTimer):

  • test_skips_moonraker_call_when_moonraker_is_none, reproduces the crash; passes after fix.
  • test_calls_moonraker_when_in_print_and_moonraker_set, happy path.
  • test_does_not_call_moonraker_when_not_in_print, pre-existing not-in-print path.

Full suite: 1165 passed in 1.95s.

PR Checklist: (Checked-off items are either done or do not apply to this PR)

  • I have performed a self-review of my code
  • CHANGELOG.md is updated (if end-user facing)
  • Documentation updated in AT-Documentation repository
  • Sent notification to software-design/software-discussions channel (as appropriate) requesting review
  • If this PR address a GitHub issue, the issue number is referenced in the PR description

If PREP has not been run, self.moonraker is None. The reactor timer
in_print_reactor_timer would then call self.moonraker.get_file_filament_change_count
on a NoneType, raising AttributeError and crashing klipper.

Add a None check on self.moonraker alongside the in_print check, matching
the existing pattern at the td1_present property (line ~516).

Fixes AFCProject#702

Signed-off-by: SAY-5 <say.apm35@gmail.com>
@jimmyjon711
Copy link
Copy Markdown
Member

jimmyjon711 commented May 5, 2026

@SAY-5 I don't disagree with this change, but are you running AFC with the PREP delayed gcode commented out? PREP should ALWAYS run upon starting/restarting klipper since this sets the initial state of all lanes and other things.

I am just curious on how you are running AFC if PREP is not being ran, or is it AFC fails to connect to moonraker sometimes?

Edit: Just noticed this fixes an issue, maybe you are just addressing this :-)

@SAY-5
Copy link
Copy Markdown
Author

SAY-5 commented May 6, 2026

Glad you got it sorted! Anything else surfacing?

Copy link
Copy Markdown
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

This PR fixes a crash in extras/AFC.py where in_print_reactor_timer could dereference self.moonraker when it is None (e.g., when PREP hasn’t been run), matching the existing guard style used elsewhere (like td1_present). It also adds focused unit tests to reproduce the failure and validate the guarded behavior.

Changes:

  • Add a self.moonraker is not None guard to prevent NoneType dereference in in_print_reactor_timer.
  • Add unit tests covering: moonraker None case, happy path with moonraker set, and not-in-print path.

Reviewed changes

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

File Description
extras/AFC.py Guards Moonraker access in in_print_reactor_timer to prevent crashes when Moonraker isn’t initialized.
tests/test_AFC.py Adds regression and behavior tests around in_print_reactor_timer Moonraker guarding.
Comments suppressed due to low confidence (1)

extras/AFC.py:554

  • The new guard if in_print and self.moonraker is not None: now skips the entire block when Moonraker isn’t initialized. That block also updates the current lane’s buffer error position (used to avoid false-positive fault detection), which previously ran whenever in_print was true. To avoid an unintended behavior change, consider keeping if in_print: for the lane/buffer update and only guarding the Moonraker metadata lookup (and any variables that strictly depend on it) with self.moonraker is not None.
        if in_print and self.moonraker is not None:
            # Gather file filament change count from moonraker
            self.number_of_toolchanges  = self.moonraker.get_file_filament_change_count(print_filename)
            self.current_toolchange     = -1 # Reset
            self.logger.info("Total number of toolchanges set to {}".format(self.number_of_toolchanges))

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

3 participants