Surface Google Play download errors and exit non-zero on failure - #245
Open
minner-fun wants to merge 1 commit into
Open
Surface Google Play download errors and exit non-zero on failure#245minner-fun wants to merge 1 commit into
minner-fun wants to merge 1 commit into
Conversation
`MultiProgress::println()` routes through indicatif's draw target, and `ProgressDrawTarget::term()` swaps in a hidden target whenever stderr is not a color-capable terminal. A hidden target drops the message and still returns `Ok`, so every Google Play error was discarded without a trace whenever output was piped, redirected, or run under CI, cron, or Docker without a TTY. The success messages were unaffected only because they go through `suspend()`, which runs its closure even when the draw target is hidden. Route the error messages through `suspend()` + `eprintln!` so they survive in non-interactive contexts while staying on stderr, where the draw target had been sending them all along. Also propagate a failure count out of `download_apps()` so that a failed run exits non-zero, which lets callers detect failures at all. An already-present file counts as success; unavailable apps, permission errors, exhausted retries, and version-pinned requests count as failures. Finally, reword the `InvalidApp` message: the API returns that same kind for several conditions that cannot be told apart from the response -- the app may be paid, nonexistent, restricted to particular accounts, region-locked, or incompatible with the selected device. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
The problem
Every error message in the Google Play download path is silently discarded whenever
apkeepruns without a TTY on stderr — piped, redirected, or under CI, cron, or Docker without-t. The process also exits0regardless, so a caller cannot detect the failure at all.Reproducing, before this change:
No error, no file, no non-zero exit. The same happens for a nonexistent package, a permission error, or three exhausted retries.
Why it happens
MultiProgress::println()writes through indicatif's draw target.ProgressDrawTarget::term()returnsSelf::hidden()whenstderris not a color-capable terminal, and a hidden target makeswidth()returnNone, which makesdraw()returnOk(())before emitting anything. The message is dropped, and because the result isOk, the.unwrap()at each call site does not panic either.The two success messages were unaffected only because they go through
suspend(), which is documented to run its closure even when the draw target is hidden. Every one of the seven error messages usedprintln().The change
suspend()+eprintln!. They now survive in non-interactive contexts and stay on stderr, which is where the draw target had been sending them all along.download_apps()and exit non-zero when it is greater than zero. An already-present file counts as success; unavailable apps, permission errors, exhausted retries, and version-pinned requests count as failures.InvalidAppmessage. The API returns that same error kind for several conditions that are indistinguishable in the response, so naming just one of them is misleading.After
app@1.2.3)Testing
Built with
cargo build --release(no new warnings) and ran each row of the table above against a live Google Play account. Also confirmed that2>/dev/nullleaves only theDownloading ...line on stdout, so the stdout/stderr split is intact, and that the progress bars still render normally in a terminal.The same
println()pattern exists in the APKPure, F-Droid, and Huawei App Gallery sources. This PR deliberately leaves those alone to stay reviewable; happy to follow up with the same treatment if you would like it in a separate change.🤖 Generated with Claude Code