mirror of
https://github.com/primedigitaltech/market-assistant.git
synced 2026-07-24 09:11:37 +08:00
fix(frontend): keep regen in-flight lock on client disconnect (tab switch)
Made-with: Cursor
This commit is contained in:
parent
fdf5901f76
commit
4847003a05
@ -58,6 +58,20 @@ export function generationInFlightKey() {
|
|||||||
return inFlightKey
|
return inFlightKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换页签/隐藏标签时浏览器可能中止 fetch,表现为 TypeError 等;此时服务端可能仍在执行,
|
||||||
|
* 不应清除「进行中」标记(否则按钮误恢复可点)。HTTP 4xx/5xx 仍由业务层 return,走正常清除。
|
||||||
|
*/
|
||||||
|
function isAmbiguousClientFailure(err) {
|
||||||
|
if (err == null) return false
|
||||||
|
const name = err.name || ''
|
||||||
|
if (name === 'AbortError') return true
|
||||||
|
const msg = String(err.message || err)
|
||||||
|
return /Failed to fetch|NetworkError|Load failed|ERR_NETWORK|INTERNET_DISCONNECTED|aborted|cancel/i.test(
|
||||||
|
msg,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} key
|
* @param {string} key
|
||||||
* @param {() => Promise<T>} fn
|
* @param {() => Promise<T>} fn
|
||||||
@ -67,11 +81,17 @@ export async function withGenerationInFlight(key, fn) {
|
|||||||
inFlightKey.value = key
|
inFlightKey.value = key
|
||||||
writePersisted(key)
|
writePersisted(key)
|
||||||
try {
|
try {
|
||||||
return await fn()
|
const out = await fn()
|
||||||
} finally {
|
|
||||||
if (inFlightKey.value === key) {
|
if (inFlightKey.value === key) {
|
||||||
inFlightKey.value = null
|
inFlightKey.value = null
|
||||||
writePersisted(null)
|
writePersisted(null)
|
||||||
}
|
}
|
||||||
|
return out
|
||||||
|
} catch (e) {
|
||||||
|
if (inFlightKey.value === key && !isAmbiguousClientFailure(e)) {
|
||||||
|
inFlightKey.value = null
|
||||||
|
writePersisted(null)
|
||||||
|
}
|
||||||
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -156,8 +156,8 @@ async function regenerateReport() {
|
|||||||
if (!id) return
|
if (!id) return
|
||||||
regenErr.value = ''
|
regenErr.value = ''
|
||||||
const key = `${REGEN_PREFIX}${id}`
|
const key = `${REGEN_PREFIX}${id}`
|
||||||
await withGenerationInFlight(key, async () => {
|
try {
|
||||||
try {
|
await withGenerationInFlight(key, async () => {
|
||||||
const r = await api(`/api/jobs/${id}/regenerate-report/`, {
|
const r = await api(`/api/jobs/${id}/regenerate-report/`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
@ -177,10 +177,10 @@ async function regenerateReport() {
|
|||||||
const updated = JSON.parse(text)
|
const updated = JSON.parse(text)
|
||||||
const idx = jobs.value.findIndex((x) => x.id === updated.id)
|
const idx = jobs.value.findIndex((x) => x.id === updated.id)
|
||||||
if (idx >= 0) jobs.value[idx] = updated
|
if (idx >= 0) jobs.value[idx] = updated
|
||||||
} catch (e) {
|
})
|
||||||
regenErr.value = String(e)
|
} catch (e) {
|
||||||
}
|
regenErr.value = String(e)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(loadList)
|
onMounted(loadList)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user