From 3416d82d4fbe597da2ac557de9b42b59df3b5158 Mon Sep 17 00:00:00 2001 From: Oleg Date: Sat, 8 Aug 2026 00:25:12 +0000 Subject: [PATCH] Add console logging to the push subscription flow for remote diagnosis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ensurePushSubscribed() was deliberately silent on every path (success and failure alike) — reasonable for a background enhancement, but it made "did the subscription actually work" impossible to tell apart from "quietly no-op'd" when diagnosing this over chat instead of in person. Every step now logs to the console: SW registration, new vs reused subscription, and the save-to-server result, with console.error/warn on the specific failure points (missing permission, VAPID not configured server-side, save request failing). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_012o9j9RezxbZVKQMrB7oRLY --- src/lib/push/client.ts | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/lib/push/client.ts b/src/lib/push/client.ts index 534677d..bc62e46 100644 --- a/src/lib/push/client.ts +++ b/src/lib/push/client.ts @@ -13,24 +13,36 @@ function urlBase64ToUint8Array(base64String: string): Uint8Array { /** * Registers the service worker and makes sure a push subscription exists - * and is saved server-side. Best-effort only: quietly no-ops if push isn't - * supported, permission isn't granted, or anything in the chain fails — - * this is an enhancement on top of the in-page toast, never something a - * page load should be blocked or broken by. + * and is saved server-side. Never throws or blocks the page on failure — + * this is an enhancement on top of the in-page toast — but every step logs + * to the console (visible in DevTools) since a silent no-op is otherwise + * impossible to tell apart from "it worked" when diagnosing remotely. */ export async function ensurePushSubscribed(): Promise { if (typeof window === "undefined") return; - if (!("serviceWorker" in navigator) || !("PushManager" in window)) return; - if (Notification.permission !== "granted") return; + if (!("serviceWorker" in navigator) || !("PushManager" in window)) { + console.warn("[push] not supported in this browser"); + return; + } + if (Notification.permission !== "granted") { + console.warn("[push] Notification permission is", Notification.permission, "- skipping subscribe"); + return; + } try { const registration = await navigator.serviceWorker.register("/sw.js"); await navigator.serviceWorker.ready; + console.log("[push] service worker registered:", registration.scope); let subscription = await registration.pushManager.getSubscription(); - if (!subscription) { + if (subscription) { + console.log("[push] reusing existing subscription:", subscription.endpoint); + } else { const keyRes = await fetch("/api/push/vapid-public-key"); - if (!keyRes.ok) return; // push not configured server-side yet + if (!keyRes.ok) { + console.error("[push] /api/push/vapid-public-key returned", keyRes.status, "- is VAPID configured server-side?"); + return; + } const { publicKey } = await keyRes.json(); subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, @@ -39,14 +51,20 @@ export async function ensurePushSubscribed(): Promise { // plain (non-shared) ArrayBuffer. applicationServerKey: urlBase64ToUint8Array(publicKey) as BufferSource, }); + console.log("[push] created new subscription:", subscription.endpoint); } - await fetch("/api/push/subscribe", { + const saveRes = await fetch("/api/push/subscribe", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(subscription.toJSON()), }); - } catch { - // best-effort — a failure here must never disrupt the page + if (saveRes.ok) { + console.log("[push] subscription saved server-side — done"); + } else { + console.error("[push] failed to save subscription server-side:", saveRes.status, await saveRes.text()); + } + } catch (err) { + console.error("[push] ensurePushSubscribed failed:", err); } }