fix(freshness): surface silent failures when pulling latest
queryFileContent threw on octokit errors (stale SHA 404, expired token,
network blip) and the rejection bubbled up unhandled through pullLatest
and onBadgeClick, leaving the badge stuck on "Outdated" with no log or
toast. Wrap the octokit call, log on failure, clear the cached SHA so
the next click re-resolves it, and show an error toast.
Also fix a dead `if (!user || !repo) { null }` that did nothing.
This commit is contained in:
@@ -26,6 +26,7 @@ import { useUserRepoStore } from "@/modules/repo/store/userRepo.store"
|
|||||||
import { encodeUTF8ToBase64 } from "@/utils/decodeBase64ToUTF8"
|
import { encodeUTF8ToBase64 } from "@/utils/decodeBase64ToUTF8"
|
||||||
import { getFileLanguage, isMarkdownPath } from "@/utils/fileLanguage"
|
import { getFileLanguage, isMarkdownPath } from "@/utils/fileLanguage"
|
||||||
import { filenameToNoteTitle } from "@/utils/noteTitle"
|
import { filenameToNoteTitle } from "@/utils/noteTitle"
|
||||||
|
import { errorMessage } from "@/utils/notif"
|
||||||
|
|
||||||
const LinkedNotes = defineAsyncComponent(
|
const LinkedNotes = defineAsyncComponent(
|
||||||
() => import("@/components/LinkedNotes.vue")
|
() => import("@/components/LinkedNotes.vue")
|
||||||
@@ -241,6 +242,7 @@ const onConflictCancel = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const onBadgeClick = async () => {
|
const onBadgeClick = async () => {
|
||||||
|
try {
|
||||||
if (freshnessStatus.value !== "outdated") {
|
if (freshnessStatus.value !== "outdated") {
|
||||||
await checkFreshness()
|
await checkFreshness()
|
||||||
return
|
return
|
||||||
@@ -257,6 +259,10 @@ const onBadgeClick = async () => {
|
|||||||
rawContent.value = newRaw
|
rawContent.value = newRaw
|
||||||
initialRawContent.value = newRaw
|
initialRawContent.value = newRaw
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("freshness badge click failed", error)
|
||||||
|
errorMessage("❌ Couldn't pull latest from GitHub")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -51,13 +51,22 @@ export const useNoteFreshness = ({
|
|||||||
|
|
||||||
const pullLatest = async (): Promise<string | null> => {
|
const pullLatest = async (): Promise<string | null> => {
|
||||||
if (!path.value) return null
|
if (!path.value) return null
|
||||||
|
const usedCachedSha = latestSha.value !== null
|
||||||
const remoteSha = latestSha.value ?? (await fetchLatestSha(path.value))
|
const remoteSha = latestSha.value ?? (await fetchLatestSha(path.value))
|
||||||
if (!remoteSha) {
|
if (!remoteSha) {
|
||||||
|
console.warn("pullLatest: could not resolve remote sha", { path: path.value })
|
||||||
status.value = "offline"
|
status.value = "offline"
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const fileContent = await queryFileContent(user, repo, remoteSha)
|
const fileContent = await queryFileContent(user, repo, remoteSha)
|
||||||
if (!fileContent) {
|
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"
|
status.value = "offline"
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,12 +121,12 @@ export const queryFileContent = async (
|
|||||||
repo: string,
|
repo: string,
|
||||||
sha: string
|
sha: string
|
||||||
) => {
|
) => {
|
||||||
const octokit = await getOctokit()
|
|
||||||
|
|
||||||
if (!user || !repo) {
|
if (!user || !repo) {
|
||||||
null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const octokit = await getOctokit()
|
||||||
const file = await octokit.request(
|
const file = await octokit.request(
|
||||||
"GET /repos/{owner}/{repo}/git/blobs/{file_sha}",
|
"GET /repos/{owner}/{repo}/git/blobs/{file_sha}",
|
||||||
{
|
{
|
||||||
@@ -135,6 +135,9 @@ export const queryFileContent = async (
|
|||||||
file_sha: sha
|
file_sha: sha
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
return file?.data.content ?? null
|
return file?.data.content ?? null
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("queryFileContent failed", { user, repo, sha, error })
|
||||||
|
return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user