Add console logging to the push subscription flow for remote diagnosis

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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012o9j9RezxbZVKQMrB7oRLY
This commit is contained in:
ogrechkoandClaude Sonnet 5 committed 2026-08-08 00:25:12 +00:00
1 parent 1dcf5a15a5
commit 3416d82d4f
1 file changed
+29 -11
+29 -11
View File
@@ -13,24 +13,36 @@ function urlBase64ToUint8Array(base64String: string): Uint8Array {
/** /**
* Registers the service worker and makes sure a push subscription exists * 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 * and is saved server-side. Never throws or blocks the page on failure —
* supported, permission isn't granted, or anything in the chain fails — * this is an enhancement on top of the in-page toast — but every step logs
* this is an enhancement on top of the in-page toast, never something a * to the console (visible in DevTools) since a silent no-op is otherwise
* page load should be blocked or broken by. * impossible to tell apart from "it worked" when diagnosing remotely.
*/ */
export async function ensurePushSubscribed(): Promise<void> { export async function ensurePushSubscribed(): Promise<void> {
if (typeof window === "undefined") return; if (typeof window === "undefined") return;
if (!("serviceWorker" in navigator) || !("PushManager" in window)) return; if (!("serviceWorker" in navigator) || !("PushManager" in window)) {
if (Notification.permission !== "granted") return; 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 { try {
const registration = await navigator.serviceWorker.register("/sw.js"); const registration = await navigator.serviceWorker.register("/sw.js");
await navigator.serviceWorker.ready; await navigator.serviceWorker.ready;
console.log("[push] service worker registered:", registration.scope);
let subscription = await registration.pushManager.getSubscription(); 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"); 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(); const { publicKey } = await keyRes.json();
subscription = await registration.pushManager.subscribe({ subscription = await registration.pushManager.subscribe({
userVisibleOnly: true, userVisibleOnly: true,
@@ -39,14 +51,20 @@ export async function ensurePushSubscribed(): Promise<void> {
// plain (non-shared) ArrayBuffer. // plain (non-shared) ArrayBuffer.
applicationServerKey: urlBase64ToUint8Array(publicKey) as BufferSource, 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", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify(subscription.toJSON()), body: JSON.stringify(subscription.toJSON()),
}); });
} catch { if (saveRes.ok) {
// best-effort — a failure here must never disrupt the page 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);
} }
} }