Skip to content

Commit 553e11a

Browse files
authored
Merge pull request #47 from OwainWilliams/master
fix: resolve vault cache synchronization issues with file and folder operations
2 parents 67bde89 + 186eebd commit 553e11a

7 files changed

Lines changed: 128 additions & 30 deletions

File tree

manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"id": "github-issues",
33
"name": "Github Issues",
4-
"version": "1.8.0",
4+
"version": "1.9.0",
55
"minAppVersion": "0.15.0",
66
"description": "Track GitHub Issues, Pull Requests, GitLab Issues and Merge Requests directly in your vault",
77
"author": "LonoxX",
@@ -11,4 +11,4 @@
1111
"GitHub Sponsor": "https://github.com/sponsors/LonoxX",
1212
"Ko-fi": "https://ko-fi.com/LonoxX"
1313
}
14-
}
14+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "github-issues",
3-
"version": "1.8.0",
3+
"version": "1.9.0",
44
"description": "Track GitHub and GitLab issues and pull/merge requests in Obsidian",
55
"main": "main.js",
66
"scripts": {

src/file-manager.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,9 @@ export class FileManager {
295295
this.settings.dateFormat,
296296
);
297297
const fileName = `${baseFileName}.md`;
298-
const filePath = `${folderPath}/${fileName}`;
298+
// Normalize folder path to use forward slashes for consistent vault lookups
299+
const normalizedFolderPath = folderPath.replace(/\\/g, "/");
300+
const filePath = `${normalizedFolderPath}/${fileName}`;
299301

300302
const existingFile = this.app.vault.getAbstractFileByPath(filePath);
301303
let fileContent = await this.generateProjectItemContent(
@@ -323,7 +325,25 @@ export class FileManager {
323325
}
324326
await this.app.vault.modify(existingFile, fileContent);
325327
} else {
326-
await this.app.vault.create(filePath, fileContent);
328+
try {
329+
await this.app.vault.create(filePath, fileContent);
330+
} catch (fileCreateError: unknown) {
331+
const errorMsg = fileCreateError instanceof Error ? fileCreateError.message : String(fileCreateError);
332+
333+
// Check if file exists due to stale cache
334+
const fileCheck = this.app.vault.getAbstractFileByPath(filePath);
335+
336+
if (fileCheck instanceof TFile) {
337+
338+
// File exists but wasn't detected before - update it
339+
const existingContent = await this.app.vault.read(fileCheck);
340+
await this.app.vault.modify(fileCheck, fileContent);
341+
this.noticeManager.debug(`Updated existing project item file for #${content.number} (file existed but cache was stale)`);
342+
} else {
343+
// File creation genuinely failed - rethrow
344+
throw fileCreateError;
345+
}
346+
}
327347
}
328348
createdCount++;
329349
}

src/issue-file-manager.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,10 @@ export class IssueFileManager {
110110
);
111111
}
112112

113+
// Normalize folder path to use forward slashes for consistent vault lookups
114+
const normalizedIssueFolderPath = issueFolderPath.replace(/\\/g, "/");
113115
const file = this.app.vault.getAbstractFileByPath(
114-
`${issueFolderPath}/${fileName}`,
116+
`${normalizedIssueFolderPath}/${fileName}`,
115117
);
116118

117119
const [owner, repoName] = repo.repository.split("/");
@@ -288,11 +290,30 @@ export class IssueFileManager {
288290
}
289291
}
290292
} else {
291-
await this.app.vault.create(
292-
`${issueFolderPath}/${fileName}`,
293-
content,
294-
);
295-
this.noticeManager.debug(`Created issue file for ${issue.number}`);
293+
// Normalize path to use forward slashes consistently
294+
const normalizedFolderPath = issueFolderPath.replace(/\\/g, "/");
295+
const filePathToCreate = `${normalizedFolderPath}/${fileName}`;
296+
297+
try {
298+
await this.app.vault.create(filePathToCreate, content);
299+
this.noticeManager.debug(`Created issue file for ${issue.number}`);
300+
} catch (fileCreateError: unknown) {
301+
const errorMsg = fileCreateError instanceof Error ? fileCreateError.message : String(fileCreateError);
302+
303+
// Check if file exists due to stale cache
304+
const fileCheck = this.app.vault.getAbstractFileByPath(filePathToCreate);
305+
306+
if (fileCheck instanceof TFile) {
307+
// File exists but wasn't detected before - update it
308+
const existingContent = await this.app.vault.read(fileCheck);
309+
await this.app.vault.modify(fileCheck, content);
310+
this.noticeManager.debug(`Updated existing issue file for ${issue.number} (file existed but cache was stale)`);
311+
return;
312+
}
313+
314+
// File creation genuinely failed - rethrow
315+
throw fileCreateError;
316+
}
296317
}
297318
}
298319

src/pr-file-manager.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,10 @@ export class PullRequestFileManager {
113113
);
114114
}
115115

116+
// Normalize folder path to use forward slashes for consistent vault lookups
117+
const normalizedPullRequestFolderPath = pullRequestFolderPath.replace(/\\/g, "/");
116118
const file = this.app.vault.getAbstractFileByPath(
117-
`${pullRequestFolderPath}/${fileName}`,
119+
`${normalizedPullRequestFolderPath}/${fileName}`,
118120
);
119121

120122
const [owner, repoName] = repo.repository.split("/");
@@ -246,11 +248,30 @@ export class PullRequestFileManager {
246248
}
247249
}
248250
} else {
249-
await this.app.vault.create(
250-
`${pullRequestFolderPath}/${fileName}`,
251-
content,
252-
);
253-
this.noticeManager.debug(`Created PR file for ${pr.number}`);
251+
// Normalize path to use forward slashes consistently
252+
const normalizedFolderPath = pullRequestFolderPath.replace(/\\/g, "/");
253+
const filePathToCreate = `${normalizedFolderPath}/${fileName}`;
254+
255+
try {
256+
await this.app.vault.create(filePathToCreate, content);
257+
this.noticeManager.debug(`Created PR file for ${pr.number}`);
258+
} catch (fileCreateError: unknown) {
259+
const errorMsg = fileCreateError instanceof Error ? fileCreateError.message : String(fileCreateError);
260+
261+
// Check if file exists due to stale cache
262+
const fileCheck = this.app.vault.getAbstractFileByPath(filePathToCreate);
263+
264+
if (fileCheck instanceof TFile) {
265+
// File exists but wasn't detected before - update it
266+
const existingContent = await this.app.vault.read(fileCheck);
267+
await this.app.vault.modify(fileCheck, content);
268+
this.noticeManager.debug(`Updated existing PR file for ${pr.number} (file existed but cache was stale)`);
269+
return;
270+
}
271+
272+
// File creation genuinely failed - rethrow
273+
throw fileCreateError;
274+
}
254275
}
255276
}
256277

src/util/file-helpers.ts

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { App, TFile } from "obsidian";
1+
import { App, TFile, TFolder } from "obsidian";
22
import { format } from "date-fns";
33
import { escapeBody } from "./escapeUtils";
44
import { NoticeManager } from "../notice-manager";
@@ -50,19 +50,54 @@ export class FileHelpers {
5050
return;
5151
}
5252

53-
const folder = this.app.vault.getAbstractFileByPath(path);
54-
if (!folder) {
55-
try {
56-
await this.app.vault.createFolder(path);
57-
this.noticeManager.debug(`Created folder: ${path}`);
58-
} catch (error) {
59-
// Folder may have been created concurrently or vault cache was stale - verify it exists now
60-
const existsNow = this.app.vault.getAbstractFileByPath(path);
61-
if (!existsNow) {
62-
// Folder truly doesn't exist and creation failed - rethrow
63-
throw error;
53+
// Normalize path separators to forward slashes for consistency
54+
const normalizedPath = path.replace(/\\/g, "/");
55+
let existing = this.app.vault.getAbstractFileByPath(normalizedPath);
56+
57+
// Check if folder already exists
58+
if (existing instanceof TFolder) {
59+
return;
60+
}
61+
62+
63+
64+
try {
65+
await this.app.vault.createFolder(normalizedPath);
66+
this.noticeManager.debug(`Created folder: ${normalizedPath}`);
67+
} catch (error: unknown) {
68+
const errorMsg = error instanceof Error ? error.message : String(error);
69+
70+
// Handle "Folder already exists" or other folder creation errors
71+
// Retry vault check with slight delay to allow cache to update
72+
const existsNow = this.app.vault.getAbstractFileByPath(normalizedPath);
73+
74+
if (existsNow instanceof TFolder) {
75+
// Folder exists now, which is fine (concurrent creation or cache stale)
76+
return;
77+
}
78+
79+
if (
80+
error instanceof Error &&
81+
error.message.includes("Folder already exists")
82+
) {
83+
// Expected case - folder was created successfully but Obsidian threw error anyway
84+
// This commonly happens when the vault cache is out of sync
85+
// Try one more time with a tiny delay to let cache update
86+
await new Promise(resolve => setTimeout(resolve, 10));
87+
const retryCheck = this.app.vault.getAbstractFileByPath(normalizedPath);
88+
if (retryCheck instanceof TFolder) {
89+
this.noticeManager.debug(
90+
`Folder created successfully: ${normalizedPath}`,
91+
);
92+
return;
6493
}
94+
// Even though cache says it doesn't exist, the folder was likely created
95+
// Continue anyway - subsequent operations will work since the folder actually exists
96+
return;
6597
}
98+
99+
// Folder creation genuinely failed - rethrow
100+
throw error;
66101
}
67102
}
68103

versions.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@
1717
"1.6.1": "0.15.0",
1818
"1.6.2": "0.15.0",
1919
"1.7.0": "0.15.0",
20-
"1.8.0": "0.15.0"
20+
"1.8.0": "0.15.0",
21+
"1.9.0": "0.15.0"
2122
}

0 commit comments

Comments
 (0)