fix: 写后同步失败不再弹全屏报错(降级为状态记录+自动续传) / 服务端500异常写入容器日志留痕
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
# v0.6.5 发布说明(2026-10-26)
|
||||
|
||||
## 修复
|
||||
|
||||
- **写操作不再因同步失败弹全屏报错**:此前任何一次写后同步失败(如服务端 500)都会以「应用内部错误」遮罩抛到界面,一次服务端故障会让每次点击都报错。现在写操作在本地提交成功即视为成功,同步失败仅记录状态(设置页「多端数据同步」可见原因),并由下一轮自动同步继续完成。
|
||||
- **服务端 500 留痕**:接口异常现在会连同堆栈写入容器日志(`docker logs internlog-sync`),用于定位「同步服务返回 500」的真实原因。
|
||||
|
||||
## 部署
|
||||
|
||||
- 服务器:`cd /opt/daywork && git pull && cd server && docker compose up -d --build`
|
||||
- 桌面 / 安卓:安装 0.6.5(或继续用 0.6.2+ 旧版客户端,报错遮罩问题主要影响 0.6.4 网页端)
|
||||
+2
-2
File diff suppressed because one or more lines are too long
+2
-2
@@ -1,2 +1,2 @@
|
||||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./web-CAumy6rT.js","./index-DHLkCnnx.js","./index-BuZbSc5_.css"])))=>i.map(i=>d[i]);
|
||||
import{r as s,_ as i}from"./index-DHLkCnnx.js";var t;(function(e){e.Documents="DOCUMENTS",e.Data="DATA",e.Library="LIBRARY",e.Cache="CACHE",e.External="EXTERNAL",e.ExternalStorage="EXTERNAL_STORAGE"})(t||(t={}));var a;(function(e){e.UTF8="utf8",e.ASCII="ascii",e.UTF16="utf16"})(a||(a={}));const E=s("Filesystem",{web:()=>i(()=>import("./web-CAumy6rT.js"),__vite__mapDeps([0,1,2]),import.meta.url).then(e=>new e.FilesystemWeb)});export{t as Directory,a as Encoding,E as Filesystem};
|
||||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./web-D_9V1YkE.js","./index-BfUIIJpW.js","./index-BuZbSc5_.css"])))=>i.map(i=>d[i]);
|
||||
import{r as s,_ as i}from"./index-BfUIIJpW.js";var t;(function(e){e.Documents="DOCUMENTS",e.Data="DATA",e.Library="LIBRARY",e.Cache="CACHE",e.External="EXTERNAL",e.ExternalStorage="EXTERNAL_STORAGE"})(t||(t={}));var a;(function(e){e.UTF8="utf8",e.ASCII="ascii",e.UTF16="utf16"})(a||(a={}));const E=s("Filesystem",{web:()=>i(()=>import("./web-D_9V1YkE.js"),__vite__mapDeps([0,1,2]),import.meta.url).then(e=>new e.FilesystemWeb)});export{t as Directory,a as Encoding,E as Filesystem};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -8,7 +8,7 @@
|
||||
<link rel="icon" href="./icons/icon.svg" type="image/svg+xml" />
|
||||
<link rel="apple-touch-icon" href="./icons/icon-192.png" />
|
||||
<title>实习工作日志</title>
|
||||
<script type="module" crossorigin src="./assets/index-DHLkCnnx.js"></script>
|
||||
<script type="module" crossorigin src="./assets/index-BfUIIJpW.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-BuZbSc5_.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "intern-log",
|
||||
"private": true,
|
||||
"version": "0.6.4",
|
||||
"version": "0.6.5",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -159,14 +159,15 @@ export async function syncWithStoredConfig(): Promise<SyncResult> {
|
||||
return runSync({ baseUrl: await baseOf(), username: creds.username, password: creds.password })
|
||||
}
|
||||
|
||||
// 界面写操作完成后调用:立即推送差异并以服务器快照重建缓存(失败会把缓存回退到服务器真值)
|
||||
// 界面写操作完成后调用:立即推送差异并以服务器快照重建缓存
|
||||
// 注意:绝不向界面抛出——写操作本身已在本地提交成功,同步失败只记录状态
|
||||
// (设置页可见 + 下一轮自动同步续传),否则一次服务端故障会把每次点击都变成全屏报错
|
||||
export async function flushAfterWrite(): Promise<void> {
|
||||
try {
|
||||
await syncWithStoredConfig()
|
||||
} catch (e) {
|
||||
syncLastError.value = e instanceof Error ? e.message : String(e)
|
||||
try { await syncWithStoredConfig() } catch { /* 服务器不可达:本地暂存修改,下次自动推送或全量刷新时对齐 */ }
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
+2
-1
@@ -621,7 +621,8 @@ setInterval(doBackup, 24 * 60 * 60 * 1000)
|
||||
// ---------- HTTP 服务 ----------
|
||||
const server = http.createServer((req, res) => {
|
||||
handle(req, res).catch(err => {
|
||||
json(res, 500, { error: err.message || 'server error' })
|
||||
console.error('[api] ' + req.method + ' ' + req.url + ' -> 500: ' + ((err && (err.stack || err.message)) || String(err)))
|
||||
json(res, 500, { error: (err && err.message) || 'server error' })
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user