Repository navigation
Add a Debug screen with crash history, and stop the HA sync crashing the app - #6
Merged
Merged
Conversation
The app is reportedly crashing repeatedly. That matters beyond the crash itself: repeated crashes get an app force-stopped, and a force-stop cancels every AlarmManager entry it owned - which is exactly the failure being chased, an alarm that silently stops existing overnight. Makes crashes visible. This build is sideloaded, so nothing collects crashes and reading logcat needs a computer and a cable, leaving a background crash completely invisible from the phone. CrashRecorder stores the last stack trace and Settings shows it with a copy button. The handler chains to the previous one, so the system still behaves exactly as before. Fixes a path that could produce one. HaApiClient.pushSync built its Request outside the try, and Request.Builder.url throws IllegalArgumentException on a malformed base URL - which the user types by hand - while the catch covered only IOException. Anything else escaped into HaSyncService's lifecycleScope, which has no exception handler, killing the process. That loop re-runs on every state change and every service start, so it would crash again and again. The request is now built inside the try, non-IO exceptions are caught and logged, the collect body is guarded, and HaSyncPayload no longer calls nextTriggerAtMillis on rows that would throw. Whether this is the crash being seen is unconfirmed - that is what the recorder is for. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01C7x8v5c5Lu29PBWy1LdfCe
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.
Why this is very likely the whole thing
A repeatedly crashing app gets force-stopped by Android — and a force-stop cancels every
AlarmManagerentry the app owned. That is exactly the failure being chased: an alarm that silently stops existing overnight, with the app's own database still showing it as enabled.It fits every observation: short alarms ring (app alive), long ones don't, the native alarm indicator disappears while our widget still shows the alarm,
binary_sensor.*_ringingnever fires, and there are no logs — because the entry was gone before the trigger time.Settings → Debug
Crashes readable from the phone, no adb:
That last one is the point. Chasing this one screenshot at a time is what made it slow; now it's a single paste.
Reachable from a permanent Settings entry, and from the crash warning in Alarm reliability when there's something to look at.
A path that produces exactly this crash
HaApiClient.pushSyncbuilt itsRequestoutside the try, andRequest.Builder.urlthrowsIllegalArgumentExceptionon a malformed base URL — which is typed by hand. The catch covered onlyIOException, so anything else escaped intoHaSyncService'slifecycleScope, which has no exception handler, killing the process. That loop re-runs on every state change and every service start, so it would crash repeatedly.Fixed: request built inside the try, non-
IOExceptioncaught and logged, thecollectbody guarded, andHaSyncPayloadno longer callsnextTriggerAtMillis()on rows that would throw.Honest status
I have not confirmed the crash you're seeing is this one — that's what the Debug screen is for. Three times I've been confident and wrong; what's different is that this build reports rather than leaving me to infer.
Not verified
Uncompiled here —
./gradlew assembleDebugfirst.