mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-02-03 14:11:47 +01:00
🎨 文件系统读取或写入失败时退出内核 https://github.com/siyuan-note/siyuan/issues/7707
This commit is contained in:
parent
60f390d9e0
commit
7a078d3689
18 changed files with 3 additions and 162 deletions
|
|
@ -507,9 +507,6 @@
|
|||
"useDefault": "Open with default program",
|
||||
"previous": "Previous",
|
||||
"next": "Next",
|
||||
"lockFile0": "Unable to access data",
|
||||
"lockFile1": "The data file has been locked by another program",
|
||||
"lockFile2": "If the problem still occurs frequently in subsequent use, please report it via <a href=\"https://github.com/siyuan-note/siyuan/issues\" target=\"_blank\">GitHub Issues</a>",
|
||||
"kernelFault0": "Kernel connection interrupted...",
|
||||
"kernelFault1": "Please check if the network connection and kernel process is normal",
|
||||
"kernelFault2": "If the problem still occurs after restarting, please report it via <a href=\"https://github.com/siyuan-note/siyuan/issues\" target=\"_blank\">GitHub Issues</a>",
|
||||
|
|
|
|||
|
|
@ -507,9 +507,6 @@
|
|||
"useDefault": "Abrir con el programa por defecto",
|
||||
"previous": "Anterior",
|
||||
"next": "Siguiente",
|
||||
"lockFile0": "No se puede acceder a los datos",
|
||||
"lockFile1": "El archivo de datos ha sido bloqueado por otro programa",
|
||||
"lockFile2": "Si el problema sigue ocurriendo con frecuencia en el uso posterior, infórmelo a través de <a href=\"https://github.com/siyuan-note/siyuan/issues\" target=\"_blank\">Problemas en GitHub</a>",
|
||||
"kernelFault0": "Conexión del kernel interrumpida...",
|
||||
"kernelFault1": "Verifique si la conexión de red y los procesos del kernel son normales",
|
||||
"kernelFault2": "Si el problema sigue produciéndose después de reiniciar, comuníquelo a través de <a href=\"https://github.com/siyuan-note/siyuan/issues\" target=\"_blank\">Problemas en GitHub</a>",
|
||||
|
|
|
|||
|
|
@ -507,9 +507,6 @@
|
|||
"useDefault": "Ouvrir avec le programme par défaut",
|
||||
"previous": "Précédent",
|
||||
"next": "Prochain",
|
||||
"lockFile0": "Impossible d'accéder aux données",
|
||||
"lockFile1": "Le fichier de données a été verrouillé par un autre programme",
|
||||
"lockFile2": "Si le problème se produit encore fréquemment lors d'une utilisation ultérieure, veuillez le signaler via <a href=\"https://github.com/siyuan-note/siyuan/issues\" target=\"_blank\">GitHub Issues</a>",
|
||||
"kernelFault0": "Connexion au noyau interrompue...",
|
||||
"kernelFault1": "Veuillez vérifier si la connexion réseau et les processus du noyau sont normaux",
|
||||
"kernelFault2": "Si le problème persiste après le redémarrage, veuillez le signaler via <a href=\"https://github.com/siyuan-note/siyuan/issues\" target=\"_blank\">GitHub Issues</a>",
|
||||
|
|
|
|||
|
|
@ -507,9 +507,6 @@
|
|||
"useDefault": "使用預設程式打開",
|
||||
"previous": "上一個",
|
||||
"next": "下一個",
|
||||
"lockFile0": "無法存取資料",
|
||||
"lockFile1": "資料檔案已被其他程式鎖定",
|
||||
"lockFile2": "如果後續使用仍然頻繁出現該問題,請通過<a href=\"https://ld246.com/article/1649901726096\" target=\"_blank\">這裡回饋</a>",
|
||||
"kernelFault0": "kernel連接中斷...",
|
||||
"kernelFault1": "請檢查網絡連接和內核進程是否正常",
|
||||
"kernelFault2": "如果重啟後仍然出現該問題,請通過<a href=\"https://ld246.com/article/1649901726096\" target=\"_blank\">這裡回饋</a>",
|
||||
|
|
|
|||
|
|
@ -507,9 +507,6 @@
|
|||
"useDefault": "使用默认程序打开",
|
||||
"previous": "上一个",
|
||||
"next": "下一个",
|
||||
"lockFile0": "无法存取数据",
|
||||
"lockFile1": "数据文件已被其他程序锁定",
|
||||
"lockFile2": "如果后续使用仍然频繁出现该问题,请通过<a href=\"https://ld246.com/article/1649901726096\" target=\"_blank\">这里反馈</a>",
|
||||
"kernelFault0": "内核连接中断...",
|
||||
"kernelFault1": "请检查网络连接和内核进程是否正常",
|
||||
"kernelFault2": "如果重启后仍然出现该问题,请通过<a href=\"https://ld246.com/article/1649901726096\" target=\"_blank\">这里反馈</a>",
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import {openNewWindowById} from "../window/openNewWindow";
|
|||
/// #endif
|
||||
import {disabledProtyle} from "../protyle/util/onGet";
|
||||
import {fetchPost} from "../util/fetch";
|
||||
import {lockFile} from "../dialog/processSystem";
|
||||
import {showMessage} from "../dialog/message";
|
||||
|
||||
export class BlockPanel {
|
||||
|
|
@ -245,11 +244,6 @@ export class BlockPanel {
|
|||
private initProtyle(editorElement: HTMLElement) {
|
||||
const index = parseInt(editorElement.getAttribute("data-index"));
|
||||
fetchPost("api/block/getBlockInfo", {id: this.nodeIds[index]}, (response) => {
|
||||
if (response.code === 2) {
|
||||
// 文件被锁定
|
||||
lockFile(response.data);
|
||||
return false;
|
||||
}
|
||||
if (response.code === 3) {
|
||||
showMessage(response.msg);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import {Constants} from "../constants";
|
||||
import {fetchPost} from "../util/fetch";
|
||||
/// #if !MOBILE
|
||||
import {getAllModels} from "../layout/getAll";
|
||||
import {exportLayout} from "../layout/util";
|
||||
/// #endif
|
||||
/// #if !BROWSER
|
||||
|
|
@ -29,47 +28,6 @@ export const lockScreen = () => {
|
|||
/// #endif
|
||||
};
|
||||
|
||||
export const lockFile = (id: string) => {
|
||||
const html = `<div class="b3-dialog__scrim"></div>
|
||||
<div class="b3-dialog__container">
|
||||
<div class="b3-dialog__header" onselectstart="return false;">🔒 ${window.siyuan.languages.lockFile0} <small>v${Constants.SIYUAN_VERSION}</small></div>
|
||||
<div class="b3-dialog__content">
|
||||
<p>${window.siyuan.languages.lockFile1}</p>
|
||||
<p>${window.siyuan.languages.lockFile2}</p>
|
||||
</div>
|
||||
<div class="b3-dialog__action">
|
||||
<button class="b3-button b3-button--cancel">${window.siyuan.languages.closeTab}</button>
|
||||
<div class="fn__space"></div>
|
||||
<button class="b3-button b3-button--text">${window.siyuan.languages.retry}</button>
|
||||
</div>
|
||||
</div>`;
|
||||
let logElement = document.getElementById("errorLog");
|
||||
if (logElement) {
|
||||
logElement.innerHTML = html;
|
||||
} else {
|
||||
document.body.insertAdjacentHTML("beforeend", `<div id="errorLog" class="b3-dialog b3-dialog--open">${html}</div>`);
|
||||
logElement = document.getElementById("errorLog");
|
||||
}
|
||||
logElement.querySelector(".b3-button--cancel").addEventListener("click", () => {
|
||||
/// #if !MOBILE
|
||||
getAllModels().editor.find((item) => {
|
||||
if (item.editor.protyle.block.rootID === id) {
|
||||
item.parent.parent.removeTab(item.parent.id, false, false);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
logElement.remove();
|
||||
/// #endif
|
||||
});
|
||||
logElement.querySelector(".b3-button--text").addEventListener("click", () => {
|
||||
fetchPost("/api/filetree/lockFile", {id}, (response) => {
|
||||
if (response.code === 0) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const kernelError = () => {
|
||||
let iosReStart = "";
|
||||
if (window.siyuan.config.system.container === "ios" && window.webkit?.messageHandlers) {
|
||||
|
|
@ -162,10 +120,6 @@ export const exitSiYuan = () => {
|
|||
};
|
||||
|
||||
export const transactionError = (data: { code: number, data: string }) => {
|
||||
if (data.code === 1) {
|
||||
lockFile(data.data);
|
||||
return;
|
||||
}
|
||||
if (document.getElementById("transactionError")) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import {pushBack} from "../util/backForward";
|
|||
import {Asset} from "../asset";
|
||||
import {Layout} from "../layout";
|
||||
import {hasClosestBlock, hasClosestByAttribute, hasClosestByClassName,} from "../protyle/util/hasClosest";
|
||||
import {lockFile, setTitle} from "../dialog/processSystem";
|
||||
import {setTitle} from "../dialog/processSystem";
|
||||
import {zoomOut} from "../menus/protyle";
|
||||
import {countBlockWord, countSelectWord} from "../layout/status";
|
||||
import {showMessage} from "../dialog/message";
|
||||
|
|
@ -34,11 +34,6 @@ export const openFileById = (options: {
|
|||
removeCurrentTab?: boolean
|
||||
}) => {
|
||||
fetchPost("/api/block/getBlockInfo", {id: options.id}, (data) => {
|
||||
if (data.code === 2) {
|
||||
// 文件被锁定
|
||||
lockFile(data.data);
|
||||
return;
|
||||
}
|
||||
if (data.code === 3) {
|
||||
showMessage(data.msg);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import {disabledProtyle, onGet} from "../protyle/util/onGet";
|
|||
import {addLoading} from "../protyle/ui/initUI";
|
||||
import {focusBlock} from "../protyle/util/selection";
|
||||
import {scrollCenter} from "../util/highlightById";
|
||||
import {lockFile} from "../dialog/processSystem";
|
||||
import {hasClosestByAttribute} from "../protyle/util/hasClosest";
|
||||
import {setEditMode} from "../protyle/util/setEditMode";
|
||||
import {hideElements} from "../protyle/ui/hideElements";
|
||||
|
|
@ -40,11 +39,6 @@ export const openMobileFileById = (id: string, action = [Constants.CB_GET_HL]) =
|
|||
}
|
||||
|
||||
fetchPost("/api/block/getBlockInfo", {id}, (data) => {
|
||||
if (data.code === 2) {
|
||||
// 文件被锁定
|
||||
lockFile(data.data);
|
||||
return;
|
||||
}
|
||||
if (data.code === 3) {
|
||||
showMessage(data.msg);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import {confirmDialog} from "../../dialog/confirmDialog";
|
|||
import {getThemeMode, setInlineStyle} from "../../util/assets";
|
||||
import {fetchPost} from "../../util/fetch";
|
||||
import {Dialog} from "../../dialog";
|
||||
import {lockFile} from "../../dialog/processSystem";
|
||||
import {pathPosix} from "../../util/pathName";
|
||||
import {replaceLocalPath} from "../../editor/rename";
|
||||
import {setStorageVal} from "../util/compatibility";
|
||||
|
|
@ -464,11 +463,6 @@ const getExportPath = (option: { type: string, id: string }, removeAssets?: bool
|
|||
fetchPost("/api/block/getBlockInfo", {
|
||||
id: option.id
|
||||
}, (response) => {
|
||||
if (response.code === 2) {
|
||||
// 文件被锁定
|
||||
lockFile(response.data);
|
||||
return;
|
||||
}
|
||||
if (response.code === 3) {
|
||||
showMessage(response.msg);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import {lockFile, setTitle} from "../../dialog/processSystem";
|
||||
import {setTitle} from "../../dialog/processSystem";
|
||||
import {Constants} from "../../constants";
|
||||
import {hideElements} from "../ui/hideElements";
|
||||
import {genEmptyElement} from "../../block/util";
|
||||
|
|
@ -36,12 +36,6 @@ export const onGet = (data: IWebSocketData, protyle: IProtyle, action: string[]
|
|||
}
|
||||
protyle.notebookId = data.data.box;
|
||||
protyle.path = data.data.path;
|
||||
if (data.code === 2) {
|
||||
// 文件被锁定
|
||||
protyle.block.rootID = data.data;
|
||||
lockFile(data.data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.data.eof) {
|
||||
if (action.includes(Constants.CB_GET_BEFORE)) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import {blockRender} from "../markdown/blockRender";
|
|||
import {processRender} from "../util/processCode";
|
||||
import {highlightRender} from "../markdown/highlightRender";
|
||||
import {hasClosestBlock, hasClosestByAttribute} from "../util/hasClosest";
|
||||
import {lockFile} from "../../dialog/processSystem";
|
||||
import {setFold} from "../../menus/protyle";
|
||||
import {onGet} from "../util/onGet";
|
||||
/// #if !MOBILE
|
||||
|
|
@ -69,10 +68,7 @@ const promiseTransaction = () => {
|
|||
} else {
|
||||
promiseTransaction();
|
||||
}
|
||||
if (response.code === 1) {
|
||||
lockFile(protyle.block.rootID);
|
||||
return;
|
||||
}
|
||||
|
||||
countBlockWord([], protyle.block.rootID, true);
|
||||
/// #if MOBILE
|
||||
if ((0 !== window.siyuan.config.sync.provider || (0 === window.siyuan.config.sync.provider && !needSubscribe(""))) &&
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import {Tab} from "../layout/Tab";
|
|||
import {Editor} from "../editor";
|
||||
import {onGet} from "../protyle/util/onGet";
|
||||
import {scrollCenter} from "./highlightById";
|
||||
import {lockFile} from "../dialog/processSystem";
|
||||
import {zoomOut} from "../menus/protyle";
|
||||
import {showMessage} from "../dialog/message";
|
||||
import {saveScroll} from "../protyle/scroll/saveScroll";
|
||||
|
|
@ -39,11 +38,6 @@ const focusStack = async (stack: IBackStack) => {
|
|||
}
|
||||
if (wnd) {
|
||||
const info = await fetchSyncPost("/api/block/getBlockInfo", {id: stack.id});
|
||||
if (info.code === 2) {
|
||||
// 文件被锁定
|
||||
lockFile(info.data);
|
||||
return false;
|
||||
}
|
||||
if (info.code === 3) {
|
||||
showMessage(info.msg);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import {getCurrentWindow} from "@electron/remote";
|
|||
import {Constants} from "../constants";
|
||||
import {Tab} from "../layout/Tab";
|
||||
import {fetchPost} from "../util/fetch";
|
||||
import {lockFile} from "../dialog/processSystem";
|
||||
import {showMessage} from "../dialog/message";
|
||||
|
||||
export const openNewWindow = (tab: Tab) => {
|
||||
|
|
@ -23,11 +22,6 @@ export const openNewWindow = (tab: Tab) => {
|
|||
|
||||
export const openNewWindowById = (id: string) => {
|
||||
fetchPost("api/block/getBlockInfo", {id}, (response) => {
|
||||
if (response.code === 2) {
|
||||
// 文件被锁定
|
||||
lockFile(response.data);
|
||||
return false;
|
||||
}
|
||||
if (response.code === 3) {
|
||||
showMessage(response.msg);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -194,12 +194,6 @@ func checkBlockExist(c *gin.Context) {
|
|||
|
||||
id := arg["id"].(string)
|
||||
b, err := model.GetBlock(id, nil)
|
||||
// TODO 文件被锁的情况已经在 filelock 中做了退出进程处理,不会走到应用层,所以 code 为 2 的情况应该移除
|
||||
//if errors.Is(err, filelock.ErrUnableAccessFile) {
|
||||
// ret.Code = 2
|
||||
// ret.Data = id
|
||||
// return
|
||||
//}
|
||||
if errors.Is(err, model.ErrIndexing) {
|
||||
ret.Code = 0
|
||||
ret.Data = false
|
||||
|
|
@ -405,11 +399,6 @@ func getBlockInfo(c *gin.Context) {
|
|||
id := arg["id"].(string)
|
||||
|
||||
tree, err := model.LoadTreeByID(id)
|
||||
//if errors.Is(err, filelock.ErrUnableAccessFile) {
|
||||
// ret.Code = 2
|
||||
// ret.Data = id
|
||||
// return
|
||||
//}
|
||||
if errors.Is(err, model.ErrIndexing) {
|
||||
ret.Code = 3
|
||||
ret.Msg = model.Conf.Language(56)
|
||||
|
|
@ -438,11 +427,6 @@ func getBlockInfo(c *gin.Context) {
|
|||
}
|
||||
|
||||
root, err := model.GetBlock(block.RootID, tree)
|
||||
//if errors.Is(err, filelock.ErrUnableAccessFile) {
|
||||
// ret.Code = 2
|
||||
// ret.Data = id
|
||||
// return
|
||||
//}
|
||||
if errors.Is(err, model.ErrIndexing) {
|
||||
ret.Code = 3
|
||||
ret.Data = model.Conf.Language(56)
|
||||
|
|
|
|||
|
|
@ -501,24 +501,6 @@ func createDocWithMd(c *gin.Context) {
|
|||
pushCreate(box, p, id, arg)
|
||||
}
|
||||
|
||||
func lockFile(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
||||
arg, ok := util.JsonArg(c, ret)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
id := arg["id"].(string)
|
||||
locked := model.TryAccessFileByBlockID(id)
|
||||
if !locked {
|
||||
ret.Code = -1
|
||||
ret.Msg = fmt.Sprintf(model.Conf.Language(75))
|
||||
ret.Data = map[string]interface{}{"closeTimeout": 5000}
|
||||
}
|
||||
}
|
||||
|
||||
func getDocCreateSavePath(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
|
@ -689,11 +671,6 @@ func getDoc(c *gin.Context) {
|
|||
}
|
||||
|
||||
blockCount, content, parentID, parent2ID, rootID, typ, eof, scroll, boxID, docPath, isBacklinkExpand, err := model.GetDoc(startID, endID, id, index, keyword, mode, size, isBacklink)
|
||||
//if errors.Is(err, filelock.ErrUnableAccessFile) {
|
||||
// ret.Code = 2
|
||||
// ret.Data = id
|
||||
// return
|
||||
//}
|
||||
if model.ErrBlockNotFound == err {
|
||||
ret.Code = 3
|
||||
return
|
||||
|
|
|
|||
|
|
@ -89,7 +89,6 @@ func ServeAPI(ginServer *gin.Engine) {
|
|||
ginServer.Handle("POST", "/api/filetree/getDocCreateSavePath", model.CheckAuth, getDocCreateSavePath)
|
||||
ginServer.Handle("POST", "/api/filetree/getRefCreateSavePath", model.CheckAuth, getRefCreateSavePath)
|
||||
ginServer.Handle("POST", "/api/filetree/changeSort", model.CheckAuth, model.CheckReadonly, changeSort)
|
||||
ginServer.Handle("POST", "/api/filetree/lockFile", model.CheckAuth, lockFile)
|
||||
ginServer.Handle("POST", "/api/filetree/createDocWithMd", model.CheckAuth, model.CheckReadonly, createDocWithMd)
|
||||
ginServer.Handle("POST", "/api/filetree/createDailyNote", model.CheckAuth, model.CheckReadonly, createDailyNote)
|
||||
ginServer.Handle("POST", "/api/filetree/createDoc", model.CheckAuth, model.CheckReadonly, createDoc)
|
||||
|
|
|
|||
|
|
@ -527,19 +527,6 @@ func (box *Box) UpdateHistoryGenerated() {
|
|||
boxLatestHistoryTime[box.ID] = time.Now()
|
||||
}
|
||||
|
||||
func TryAccessFileByBlockID(id string) (ok bool) {
|
||||
bt := treenode.GetBlockTree(id)
|
||||
if nil == bt {
|
||||
return
|
||||
}
|
||||
p := filepath.Join(util.DataDir, bt.BoxID, bt.Path)
|
||||
|
||||
if !gulu.File.IsExist(p) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func getBoxesByPaths(paths []string) (ret map[string]*Box) {
|
||||
ret = map[string]*Box{}
|
||||
for _, p := range paths {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue