Conversation
update_selections() and load_selections() read the printer's flush_volumes_matrix and flush_volumes_vector app-config values by splitting on '|' and passing every token through boost::lexical_cast<double>. has_printer_setting() returns true even when the stored value is an empty string, so the split produces a single empty token and lexical_cast throws boost::bad_lexical_cast. Nothing catches it, so the whole preset load bails out. I ran into this on a Snapmaker U1. Syncing filament from the printer can write empty flush volume values into the active printer combo, and after that the app throws "bad lexical cast: source type value could not be interpreted as target". Because the bad combo gets reloaded on the next launch, it then crashes on startup every time until you hand-edit the config. Same issue as Snapmaker#616. This adds a small parse_flush_volume_list() helper that skips empty or malformed tokens instead of throwing, the same way the flush_multiplier value right below it is already guarded. Valid data parses exactly as before. An empty or corrupt value now just keeps the existing defaults instead of taking down the load.
3 tasks
Author
|
Status update. Confirmed the root cause and reproduced both failure modes on a real U1 this session. Sync reads a cached filament snapshot and never refreshes it at sync time. Filament presence on this machine comes from per slot motion sensors, so a slot reads empty during a runout or a load, and Orca caches whatever it last saw, sometimes for a long time. Both failure modes reproduced live:
This PR is the crash safety layer and stands on its own. Two follow ups are in testing: the collector should return the loaded filaments regardless of project size, and sync should pull a live reading instead of trusting the cache. The logic for both is verified with standalone tests. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the "bad lexical cast: source type value could not be interpreted as target" crash reported in #616.
What is happening: update_selections() and load_selections() parse the printer flush_volumes_matrix and flush_volumes_vector values from app config by splitting on "|" and running each token through boost::lexical_cast. has_printer_setting() returns true even when the stored value is an empty string, so the split gives back a single empty token and lexical_cast throws boost::bad_lexical_cast. Nothing catches it, so the whole preset load aborts.
How you run into it: on a Snapmaker U1, syncing filament from the printer can write empty flush volume values into the active printer combo. After that the app throws the bad lexical cast, and because the corrupt combo is reloaded on the next launch it crashes on startup every time until the config is edited by hand.
The fix: a small parse_flush_volume_list() helper that tolerates an empty string and skips empty or malformed tokens instead of throwing, the same way the flush_multiplier value right below it is already guarded. Valid data parses exactly as before. An empty or corrupt value now keeps the existing defaults instead of taking down the load.
I tested the parsing against an empty string, a normal single filament vector, a full 4x4 flush matrix, an empty middle token, and a malformed token. The old code throws on the empty and malformed inputs, the new code returns identical values for good data and no longer throws.
One note: this stops the crash. It does not address why the sync writes empty flush volumes in the first place (the remap that collapses to zero filaments), which looks like a separate issue worth its own look.