mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-04 13:11:35 +02:00
Every dispatch upload that failed carried one sentence: "Failed to upload file to printer. Check if SD card is inserted and properly formatted (FAT32/exFAT)." The reporter got it after a TLS handshake failure and restarted the printer on the strength of it. That could not have helped. The handshake never reached the printer's filesystem, and the cool-off that made the next dispatch fail the same way lives in Bambuddy's own memory, where power-cycling a printer does not reach. because the advice was known not to work. It survived in the string people actually read, so the failure mode that fix closed was still reachable through the UI. reachable through the UI. The information was never missing. connect() separates five failure classes and upload_file() separates 553/552/550, each with its own log line -- 553 even logs a spelled-out list of storage causes -- and then both returned a bare False. The dispatch had nothing left to work with and guessed storage for all of them. So the reason now travels with the result. The client records an FtpFailure (kind, detail, and the reply code where the server gave one) on every failure branch, and upload_file_async fills in a report object the CALLER owns. Not a per-IP dict beside _mode_cache: those describe a printer and are right to share, while this describes one operation, and a background timelapse fetch running beside a dispatch would overwrite the dispatch's reason with its own -- reporting the wrong cause with total confidence, which is this bug again rather than a fix for it. describe_upload_failure() picks the wording, and lives next to the kinds so the two cannot drift. A 553 or 552 keeps the card advice, which is the case it was written for, and quotes the reply code so a queue entry and a support bundle line up. A handshake failure says the file service answered without TLS and that the card is not involved. A refusal points at the access code, a timeout at the network, and anything unclassified says so and points at the log rather than picking a plausible cause. A wrong instruction costs more than a vague one: it sends someone to work on hardware that is fine. Nothing prescribes a power cycle. The failure notification now carries the same sentence the queue shows, instead of its own fixed "Failed to upload file to printer", so a push and the screen cannot disagree about what happened. Tests cover the classification, the report reaching the caller through the retry loop, two callers not crossing, the queue entry itself, and one line per message branch -- without that last one, deleting the access-code or timeout branch left every other assertion passing, since they only check that the card is not named and the generic message satisfies that too. The card-advice test keys on the instruction rather than the words "SD card", because the handshake message names the card in order to rule it out.