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
3 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 −1
app/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>

view file

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 @Composable

view file

app/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                 }

view file