b61ca4e4a735
name the debug build peach-debug and surface the real pairing rejection reason in debug builds
- time
- 2026-07-25 03:06 UTC · 3 months ago
- machine
- koh2
- agent
- claude-opus-5
- session
- pairing diagnostics
- parent
- 8b5c0b5f6a0a
↓ peach-android-b61ca4e4.tar.gzatlas at this save
files changed3 files
app/src/debug/res/values/strings.xml+6 −0app/src/main/java/com/peachpasswords/ui/pairing/CodePairScreen.kt+6 −0app/src/main/java/com/peachpasswords/ui/pairing/CodePairViewModel.kt+9 −1app/src/debug/res/values/strings.xml+6 −0
@@ -0,0 +1,6 @@1+<?xml version="1.0" encoding="utf-8"?>2+<resources>3+ <!-- Debug installs alongside the real app (applicationId .debug); a distinct4+ launcher name is the only way to tell the two icons apart. -->5+ <string name="app_name">peach-debug</string>6+</resources>app/src/main/java/com/peachpasswords/ui/pairing/CodePairScreen.kt+6 −0
@@ -1,5 +1,6 @@11 package com.peachpasswords.ui.pairing22 3+import com.peachpasswords.BuildConfig34 import androidx.compose.foundation.background45 import androidx.compose.foundation.clickable56 import androidx.compose.foundation.shape.RoundedCornerShape@@ -185,7 +186,12 @@185186 "vault_locked" -> "Unlock your vault first — pairing shares the key that protects it."186187 "no_local_network" -> "This phone isn't on a Wi-Fi network, so there's no address to hand out."187188 "sas_mismatch" -> "The codes didn't match, so nothing was saved. That's the right outcome if you didn't expect a connection."189+ // Every other reason collapsed into this one sentence, which is fine for a190+ // user and useless for anyone debugging: "bad_token", "no_hello" and a raw191+ // exception message all looked identical on screen. Debug builds show the192+ // real one.188193 else -> "Something interrupted the connection. Try again."194+ .let { if (BuildConfig.DEBUG) "$it\n\n[$reason]" else it }189195 }190196 191197 @Composableapp/src/main/java/com/peachpasswords/ui/pairing/CodePairViewModel.kt+9 −1
@@ -1,6 +1,8 @@11 package com.peachpasswords.ui.pairing22 33 import android.content.Context4+import android.util.Log5+import com.peachpasswords.BuildConfig46 import androidx.lifecycle.ViewModel57 import androidx.lifecycle.viewModelScope68 import com.peachpasswords.sync.BatteryExemption@@ -78,7 +80,13 @@7880 is PairingEvent.Listening -> CodePairUiState.ShowingCode(event.code, event.ip, event.port)7981 is PairingEvent.Paired -> CodePairUiState.Paired(event.deviceName)8082 PairingEvent.Expired -> CodePairUiState.Expired81- is PairingEvent.Rejected -> CodePairUiState.Failed(event.reason)83+ is PairingEvent.Rejected -> {84+ // Nothing else records why a pairing attempt died, and85+ // the on-screen copy is deliberately vague. Without this86+ // a failure on someone else's phone is undiagnosable.87+ if (BuildConfig.DEBUG) Log.w("PeachPairing", "pairing rejected: ${event.reason}")88+ CodePairUiState.Failed(event.reason)89+ }8290 // Delivered via confirmationSink; the flow only sees the outcome.8391 is PairingEvent.AwaitingConfirmation -> _state.value8492 }