Enhance inverse edge creation with improved logging and error handling
Some checks are pending
Node.js build / build (20.x) (push) Waiting to run
Node.js build / build (22.x) (push) Waiting to run

- Updated the insertEdgeForward function to include detailed logging before and after the creation of inverse edges in "note_links" and "candidates" zones.
- Implemented try-catch blocks to handle potential errors during inverse edge creation without interrupting the process, making it optional.
- Enhanced logging in the createInverseEdge function to provide clearer insights into the edge creation process and any issues encountered.
This commit is contained in:
Lars 2026-02-05 16:32:22 +01:00
parent 6d5f6203c4
commit ad543248c7

View File

@ -86,15 +86,22 @@ export async function insertEdgeForward(
await insertEdgeInZone(app, editor, file, "note_links", edgeType, targetLink, settings); await insertEdgeInZone(app, editor, file, "note_links", edgeType, targetLink, settings);
// Automatically create inverse edge in target note/section // Automatically create inverse edge in target note/section
await createInverseEdge( console.log("[insertEdgeForward] About to create inverse edge (note_links), edgeType:", edgeType);
app, try {
edgeType, await createInverseEdge(
todo, app,
vocabulary, edgeType,
edgeVocabulary, todo,
settings, vocabulary,
debugLogging edgeVocabulary,
); settings,
debugLogging
);
console.log("[insertEdgeForward] createInverseEdge call completed (note_links)");
} catch (error) {
console.error("[insertEdgeForward] Error calling createInverseEdge (note_links):", error);
// Don't throw - inverse edge creation is optional
}
} else if (targetZone === "candidates") { } else if (targetZone === "candidates") {
// Insert in Kandidaten zone // Insert in Kandidaten zone
if (debugLogging) { if (debugLogging) {
@ -103,15 +110,22 @@ export async function insertEdgeForward(
await insertEdgeInZone(app, editor, file, "candidates", edgeType, targetLink, settings); await insertEdgeInZone(app, editor, file, "candidates", edgeType, targetLink, settings);
// Automatically create inverse edge in target note/section // Automatically create inverse edge in target note/section
await createInverseEdge( console.log("[insertEdgeForward] About to create inverse edge (candidates), edgeType:", edgeType);
app, try {
edgeType, await createInverseEdge(
todo, app,
vocabulary, edgeType,
edgeVocabulary, todo,
settings, vocabulary,
debugLogging edgeVocabulary,
); settings,
debugLogging
);
console.log("[insertEdgeForward] createInverseEdge call completed (candidates)");
} catch (error) {
console.error("[insertEdgeForward] Error calling createInverseEdge (candidates):", error);
// Don't throw - inverse edge creation is optional
}
} else { } else {
// Insert in source section - need to select section if multiple exist // Insert in source section - need to select section if multiple exist
// IMPORTANT: Use source note (fromNodeRef.file), not current note! // IMPORTANT: Use source note (fromNodeRef.file), not current note!
@ -242,15 +256,22 @@ export async function insertEdgeForward(
} }
// Automatically create inverse edge in target note/section // Automatically create inverse edge in target note/section
await createInverseEdge( console.log("[insertEdgeForward] About to create inverse edge, edgeType:", edgeType);
app, try {
edgeType, await createInverseEdge(
todo, app,
vocabulary, edgeType,
edgeVocabulary, todo,
settings, vocabulary,
debugLogging edgeVocabulary,
); settings,
debugLogging
);
console.log("[insertEdgeForward] createInverseEdge call completed");
} catch (error) {
console.error("[insertEdgeForward] Error calling createInverseEdge:", error);
// Don't throw - inverse edge creation is optional
}
} }
} }
@ -267,113 +288,117 @@ async function createInverseEdge(
debugLogging?: boolean debugLogging?: boolean
): Promise<void> { ): Promise<void> {
try { try {
console.log("[createInverseEdge] Starting inverse edge creation for:", forwardEdgeType); console.log("[createInverseEdge] ===== STARTING INVERSE EDGE CREATION =====");
console.log("[createInverseEdge] Forward edge type:", forwardEdgeType);
// Get canonical type and inverse // Get canonical type and inverse
const canonical = vocabulary.getCanonical(forwardEdgeType); const canonical = vocabulary.getCanonical(forwardEdgeType);
console.log("[createInverseEdge] Canonical type:", canonical);
if (!canonical) { if (!canonical) {
console.log("[createInverseEdge] No canonical type found for:", forwardEdgeType); console.log("[createInverseEdge] No canonical type found for:", forwardEdgeType);
return; // Can't create inverse without canonical type return; // Can't create inverse without canonical type
} }
const inverseCanonical = vocabulary.getInverse(canonical); const inverseCanonical = vocabulary.getInverse(canonical);
console.log("[createInverseEdge] Inverse canonical:", inverseCanonical);
if (!inverseCanonical) { if (!inverseCanonical) {
console.log("[createInverseEdge] No inverse defined for:", canonical); console.log("[createInverseEdge] No inverse defined for:", canonical);
return; // No inverse defined, skip return; // No inverse defined, skip
} }
// Get the raw inverse type (use canonical or find an alias) // Use canonical type for inverse edge (consistent and unambiguous)
const inverseEntry = edgeVocabulary.byCanonical.get(inverseCanonical); // The inverseCanonical is already the canonical type from vocabulary
const inverseEdgeType = inverseEntry?.aliases?.[0] || inverseCanonical; const inverseEdgeType = inverseCanonical;
console.log("[createInverseEdge] Forward:", forwardEdgeType, "-> Canonical:", canonical, "-> Inverse:", inverseEdgeType); console.log("[createInverseEdge] Forward:", forwardEdgeType, "-> Canonical:", canonical, "-> Inverse canonical:", inverseCanonical, "-> Using:", inverseEdgeType);
// Find target file // Find target file
const targetFileRef = todo.toNodeRef.file; const targetFileRef = todo.toNodeRef.file;
let targetFile: TFile | null = null; let targetFile: TFile | null = null;
const possiblePaths = [ const possiblePaths = [
targetFileRef, targetFileRef,
targetFileRef + ".md", targetFileRef + ".md",
targetFileRef.replace(/\.md$/, ""), targetFileRef.replace(/\.md$/, ""),
targetFileRef.replace(/\.md$/, "") + ".md", targetFileRef.replace(/\.md$/, "") + ".md",
]; ];
for (const path of possiblePaths) { for (const path of possiblePaths) {
const found = app.vault.getAbstractFileByPath(path); const found = app.vault.getAbstractFileByPath(path);
if (found && found instanceof TFile) { if (found && found instanceof TFile) {
targetFile = found; targetFile = found;
break; break;
}
} }
}
if (!targetFile) {
if (!targetFile) { const basename = targetFileRef.replace(/\.md$/, "").split("/").pop() || targetFileRef;
const basename = targetFileRef.replace(/\.md$/, "").split("/").pop() || targetFileRef; const resolved = app.metadataCache.getFirstLinkpathDest(basename, todo.fromNodeRef.file);
const resolved = app.metadataCache.getFirstLinkpathDest(basename, todo.fromNodeRef.file); if (resolved) {
if (resolved) { targetFile = resolved;
targetFile = resolved; }
} }
}
if (!targetFile) {
if (!targetFile) { console.log("[createInverseEdge] Target file not found:", targetFileRef);
console.log("[createInverseEdge] Target file not found:", targetFileRef); return;
return; }
}
// Build source link (for inverse edge, source is the original target)
// Build source link (for inverse edge, source is the original target) const sourceBasename = todo.fromNodeRef.file.replace(/\.md$/, "").split("/").pop() || todo.fromNodeRef.file;
const sourceBasename = todo.fromNodeRef.file.replace(/\.md$/, "").split("/").pop() || todo.fromNodeRef.file; const sourceLink = todo.fromNodeRef.heading
const sourceLink = todo.fromNodeRef.heading ? `${sourceBasename}#${todo.fromNodeRef.heading}`
? `${sourceBasename}#${todo.fromNodeRef.heading}` : sourceBasename;
: sourceBasename;
// Always ask user to select target section (or whole note)
// Always ask user to select target section (or whole note) // Open target file in editor first
// Open target file in editor first console.log("[createInverseEdge] Opening target file:", targetFile.path);
console.log("[createInverseEdge] Opening target file:", targetFile.path); await app.workspace.openLinkText(targetFile.path, "", false);
await app.workspace.openLinkText(targetFile.path, "", false);
// Wait a bit for the editor to be ready
// Wait a bit for the editor to be ready await new Promise(resolve => setTimeout(resolve, 100));
await new Promise(resolve => setTimeout(resolve, 100));
const targetEditor = app.workspace.activeEditor?.editor;
const targetEditor = app.workspace.activeEditor?.editor; if (!targetEditor) {
if (!targetEditor) { console.error("[createInverseEdge] Could not get editor for target file:", targetFile.path);
console.error("[createInverseEdge] Could not get editor for target file:", targetFile.path); return;
return; }
}
// Load sections from target file
// Load sections from target file const { splitIntoSections } = await import("../mapping/sectionParser");
const { splitIntoSections } = await import("../mapping/sectionParser"); const targetContent = await app.vault.read(targetFile);
const targetContent = await app.vault.read(targetFile); const sections = splitIntoSections(targetContent);
const sections = splitIntoSections(targetContent);
// Filter out special zones
// Filter out special zones const contentSections = sections.filter(
const contentSections = sections.filter( (s) => s.heading !== "Kandidaten" && s.heading !== "Note-Verbindungen"
(s) => s.heading !== "Kandidaten" && s.heading !== "Note-Verbindungen" );
);
// Show selection modal: user can choose a section or "whole note"
// Show selection modal: user can choose a section or "whole note" console.log("[createInverseEdge] Showing target selection modal, sections:", contentSections.length);
const selectedTarget = await selectTargetForInverseEdge( const selectedTarget = await selectTargetForInverseEdge(
app, app,
targetFile, targetFile,
contentSections, contentSections,
todo.toNodeRef.heading, todo.toNodeRef.heading,
debugLogging debugLogging
); );
if (!selectedTarget) { if (!selectedTarget) {
console.log("[createInverseEdge] User cancelled target selection"); console.log("[createInverseEdge] User cancelled target selection");
return; // User cancelled return; // User cancelled
} }
console.log("[createInverseEdge] Selected target:", selectedTarget.type, selectedTarget.heading || "(whole note)"); console.log("[createInverseEdge] Selected target:", selectedTarget.type, selectedTarget.heading || "(whole note)");
console.log("[createInverseEdge] Inverse edge type:", inverseEdgeType, "source link:", sourceLink); console.log("[createInverseEdge] Inverse edge type:", inverseEdgeType, "source link:", sourceLink);
try {
if (selectedTarget.type === "note_links") { if (selectedTarget.type === "note_links") {
console.log("[createInverseEdge] Calling insertEdgeInZone with note_links"); console.log("[createInverseEdge] Calling insertEdgeInZone with note_links");
await insertEdgeInZone(app, targetEditor, targetFile, "note_links", inverseEdgeType, sourceLink, settings); await insertEdgeInZone(app, targetEditor, targetFile, "note_links", inverseEdgeType, sourceLink, settings);
console.log("[createInverseEdge] insertEdgeInZone completed"); console.log("[createInverseEdge] insertEdgeInZone completed");
} else { } else {
// Use selected section // Use selected section
console.log("[createInverseEdge] Looking for section:", selectedTarget.heading);
const targetSection = await findSection(app, targetFile, selectedTarget.heading); const targetSection = await findSection(app, targetFile, selectedTarget.heading);
if (targetSection) { if (targetSection) {
console.log("[createInverseEdge] Found target section:", targetSection.heading || "(root)"); console.log("[createInverseEdge] Found target section:", targetSection.heading || "(root)");
@ -395,14 +420,12 @@ async function createInverseEdge(
} }
} }
console.log("[createInverseEdge] Inverse edge creation completed successfully"); console.log("[createInverseEdge] ===== INVERSE EDGE CREATION COMPLETED SUCCESSFULLY =====");
} catch (error) { } catch (error) {
console.error("[createInverseEdge] Error during edge insertion:", error); console.error("[createInverseEdge] ===== ERROR IN INVERSE EDGE CREATION =====");
throw error; // Re-throw to see the error console.error("[createInverseEdge] Error:", error);
} console.error("[createInverseEdge] Error stack:", error instanceof Error ? error.stack : String(error));
} catch (error) { // Don't throw - inverse edge creation is optional, but log the error
console.error("[createInverseEdge] Error creating inverse edge:", error);
// Don't throw - inverse edge creation is optional
} }
} }