QR Code Scan Failure

Nucleic-Session: 80E30D7B-70A8-479A-A9A8-7E267486EAE1
Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
2026-07-03 01:41:42 -07:00
co-authored by Nucleic
parent 308fc28448
commit 2c634e7db6
@@ -695,7 +695,35 @@ final class RemoteStore: ObservableObject {
} }
private func makeChannel(_ endpoint: NWEndpoint) -> NWFrameChannel { private func makeChannel(_ endpoint: NWEndpoint) -> NWFrameChannel {
NWFrameChannel(endpoint: endpoint) let channel = NWFrameChannel(endpoint: endpoint)
// Surface a transport-level failure with an actionable message. Without this, a refused
// connection or a denied local-network permission finished the frame stream and only
// showed up as a generic "handshake closed" — hiding the real (usually fixable) cause.
channel.onFailed = { [weak self] error in
Task { @MainActor in self?.handleTransportFailure(error) }
}
return channel
}
/// Map an `NWConnection` failure to a connectivity state the pairing/onboarding UI can act on.
/// Only meaningful while we're still establishing the link; once `.connected`, a drop is the
/// normal `.closed` → reconnect path's job.
private func handleTransportFailure(_ error: String) {
guard connectivity != .connected else { return }
connectivity = .failed(Self.friendlyTransportError(error))
}
/// Turn a raw `NWError` string into a short, fixable hint. The common onboarding failures are
/// a denied Local Network permission (EPERM / -65555) and the Mac not listening (refused).
private static func friendlyTransportError(_ error: String) -> String {
let lower = error.lowercased()
if lower.contains("denied") || lower.contains("not permitted") || lower.contains("65555") {
return "Can't reach the local network. In Settings ▸ Nucleic, allow Local Network access, then try again."
}
if lower.contains("refused") {
return "Your Mac refused the connection. Check that remote access is still on in Nucleic ▸ Settings."
}
return "Couldn't connect to your Mac — make sure it's on the same Wi‑Fi and remote access is on."
} }
private func resolveEndpoint(fingerprint: String?, lanHost: String?, lanPort: UInt16?) -> NWEndpoint? { private func resolveEndpoint(fingerprint: String?, lanHost: String?, lanPort: UInt16?) -> NWEndpoint? {