mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
recovery for tree cycle errors, #2831
This commit is contained in:
parent
a9dc62505d
commit
5dab189815
@ -56,41 +56,66 @@ class ConsistencyChecks {
|
|||||||
childToParents[childNoteId].push(parentNoteId);
|
childToParents[childNoteId].push(parentNoteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @returns {boolean} true if cycle was found and we should try again */
|
||||||
const checkTreeCycle = (noteId, path) => {
|
const checkTreeCycle = (noteId, path) => {
|
||||||
if (noteId === 'root') {
|
if (noteId === 'root') {
|
||||||
return;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (!childToParents[noteId] || childToParents[noteId].length === 0) {
|
|
||||||
logError(`No parents found for note ${noteId}`);
|
|
||||||
|
|
||||||
this.unrecoveredConsistencyErrors = true;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const parentNoteId of childToParents[noteId]) {
|
for (const parentNoteId of childToParents[noteId]) {
|
||||||
if (path.includes(parentNoteId)) {
|
if (path.includes(parentNoteId)) {
|
||||||
logError(`Tree cycle detected at parent-child relationship: ${parentNoteId} - ${noteId}, whole path: ${path}`);
|
if (this.autoFix) {
|
||||||
|
const branch = becca.getBranchFromChildAndParent(noteId, parentNoteId);
|
||||||
|
branch.markAsDeleted('cycle-autofix');
|
||||||
|
logFix(`Branch '${branch.branchId}' between child '${noteId}' and parent '${parentNoteId}' has been deleted since it was causing a tree cycle.`);
|
||||||
|
|
||||||
this.unrecoveredConsistencyErrors = true;
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logError(`Tree cycle detected at parent-child relationship: ${parentNoteId} - ${noteId}, whole path: ${path}`);
|
||||||
|
|
||||||
|
this.unrecoveredConsistencyErrors = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const newPath = path.slice();
|
const newPath = path.slice();
|
||||||
newPath.push(noteId);
|
newPath.push(noteId);
|
||||||
|
|
||||||
checkTreeCycle(parentNoteId, newPath);
|
const retryNeeded = checkTreeCycle(parentNoteId, newPath);
|
||||||
|
|
||||||
|
if (retryNeeded) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const noteIds = Object.keys(childToParents);
|
const noteIds = Object.keys(childToParents);
|
||||||
|
|
||||||
for (const noteId of noteIds) {
|
for (const noteId of noteIds) {
|
||||||
checkTreeCycle(noteId, []);
|
const retryNeeded = checkTreeCycle(noteId, []);
|
||||||
|
|
||||||
|
if (retryNeeded) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (childToParents['root'].length !== 1 || childToParents['root'][0] !== 'none') {
|
return false;
|
||||||
logError('Incorrect root parent: ' + JSON.stringify(childToParents['root']));
|
}
|
||||||
this.unrecoveredConsistencyErrors = true;
|
|
||||||
|
checkAndRepairTreeCycles() {
|
||||||
|
let treeFixed = false;
|
||||||
|
|
||||||
|
while (this.checkTreeCycles()) {
|
||||||
|
// fixing cycle means deleting branches, we might need to create a new branch to recover the note
|
||||||
|
this.findExistencyIssues();
|
||||||
|
|
||||||
|
treeFixed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (treeFixed) {
|
||||||
|
this.reloadNeeded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,7 +671,7 @@ class ConsistencyChecks {
|
|||||||
if (!this.unrecoveredConsistencyErrors) {
|
if (!this.unrecoveredConsistencyErrors) {
|
||||||
// we run this only if basic checks passed since this assumes basic data consistency
|
// we run this only if basic checks passed since this assumes basic data consistency
|
||||||
|
|
||||||
this.checkTreeCycles();
|
this.checkAndRepairTreeCycles();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.reloadNeeded) {
|
if (this.reloadNeeded) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user