diff --git a/src/components/StackedNote.vue b/src/components/StackedNote.vue index 230595c..5b180d2 100644 --- a/src/components/StackedNote.vue +++ b/src/components/StackedNote.vue @@ -26,6 +26,7 @@ import { useUserRepoStore } from "@/modules/repo/store/userRepo.store" import { encodeUTF8ToBase64 } from "@/utils/decodeBase64ToUTF8" import { getFileLanguage, isMarkdownPath } from "@/utils/fileLanguage" import { filenameToNoteTitle } from "@/utils/noteTitle" +import { errorMessage } from "@/utils/notif" const LinkedNotes = defineAsyncComponent( () => import("@/components/LinkedNotes.vue") @@ -241,21 +242,26 @@ const onConflictCancel = () => { } const onBadgeClick = async () => { - if (freshnessStatus.value !== "outdated") { - await checkFreshness() - return - } + try { + if (freshnessStatus.value !== "outdated") { + await checkFreshness() + return + } - const hasUnsavedEdits = rawContent.value !== initialRawContent.value - if (hasUnsavedEdits) { - conflictOpen.value = true - return - } + const hasUnsavedEdits = rawContent.value !== initialRawContent.value + if (hasUnsavedEdits) { + conflictOpen.value = true + return + } - const newRaw = await pullLatest() - if (newRaw !== null) { - rawContent.value = newRaw - initialRawContent.value = newRaw + const newRaw = await pullLatest() + if (newRaw !== null) { + rawContent.value = newRaw + initialRawContent.value = newRaw + } + } catch (error) { + console.error("freshness badge click failed", error) + errorMessage("❌ Couldn't pull latest from GitHub") } } diff --git a/src/hooks/useNoteFreshness.hook.ts b/src/hooks/useNoteFreshness.hook.ts index b0ce322..617ca8b 100644 --- a/src/hooks/useNoteFreshness.hook.ts +++ b/src/hooks/useNoteFreshness.hook.ts @@ -51,13 +51,22 @@ export const useNoteFreshness = ({ const pullLatest = async (): Promise => { if (!path.value) return null + const usedCachedSha = latestSha.value !== null const remoteSha = latestSha.value ?? (await fetchLatestSha(path.value)) if (!remoteSha) { + console.warn("pullLatest: could not resolve remote sha", { path: path.value }) status.value = "offline" return null } const fileContent = await queryFileContent(user, repo, remoteSha) if (!fileContent) { + console.warn("pullLatest: failed to fetch blob content", { + path: path.value, + remoteSha, + usedCachedSha + }) + // Cached SHA may be stale — clear so the next click re-resolves it. + if (usedCachedSha) latestSha.value = null status.value = "offline" return null } diff --git a/src/modules/repo/services/repo.ts b/src/modules/repo/services/repo.ts index 72fbfa5..7ba34c2 100644 --- a/src/modules/repo/services/repo.ts +++ b/src/modules/repo/services/repo.ts @@ -121,20 +121,23 @@ export const queryFileContent = async ( repo: string, sha: string ) => { - const octokit = await getOctokit() - if (!user || !repo) { - null + return null } - const file = await octokit.request( - "GET /repos/{owner}/{repo}/git/blobs/{file_sha}", - { - owner: user, - repo: repo, - file_sha: sha - } - ) - - return file?.data.content ?? null + try { + const octokit = await getOctokit() + const file = await octokit.request( + "GET /repos/{owner}/{repo}/git/blobs/{file_sha}", + { + owner: user, + repo: repo, + file_sha: sha + } + ) + return file?.data.content ?? null + } catch (error) { + console.warn("queryFileContent failed", { user, repo, sha, error }) + return null + } }