Skip to content

Commit d47929e

Browse files
authored
Revert "fix: use safeWriteJson for all JSON file writes (#3772)"
This reverts commit 1be30fc.
1 parent 19108f7 commit d47929e

File tree

18 files changed

+45
-889
lines changed

18 files changed

+45
-889
lines changed

.roo/rules-code/use-safeWriteJson.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

pnpm-lock.yaml

Lines changed: 0 additions & 66 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/api/providers/fetchers/modelCache.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import * as path from "path"
22
import fs from "fs/promises"
33

44
import NodeCache from "node-cache"
5-
import { safeWriteJson } from "../../../utils/safeWriteJson"
65

76
import { ContextProxy } from "../../../core/config/ContextProxy"
87
import { getCacheDirectoryPath } from "../../../utils/storage"
@@ -20,7 +19,7 @@ const memoryCache = new NodeCache({ stdTTL: 5 * 60, checkperiod: 5 * 60 })
2019
async function writeModels(router: RouterName, data: ModelRecord) {
2120
const filename = `${router}_models.json`
2221
const cacheDir = await getCacheDirectoryPath(ContextProxy.instance.globalStorageUri.fsPath)
23-
await safeWriteJson(path.join(cacheDir, filename), data)
22+
await fs.writeFile(path.join(cacheDir, filename), JSON.stringify(data))
2423
}
2524

2625
async function readModels(router: RouterName): Promise<ModelRecord | undefined> {

src/api/providers/fetchers/modelEndpointCache.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import * as path from "path"
22
import fs from "fs/promises"
33

44
import NodeCache from "node-cache"
5-
import { safeWriteJson } from "../../../utils/safeWriteJson"
65
import sanitize from "sanitize-filename"
76

87
import { ContextProxy } from "../../../core/config/ContextProxy"
@@ -19,7 +18,7 @@ const getCacheKey = (router: RouterName, modelId: string) => sanitize(`${router}
1918
async function writeModelEndpoints(key: string, data: ModelRecord) {
2019
const filename = `${key}_endpoints.json`
2120
const cacheDir = await getCacheDirectoryPath(ContextProxy.instance.globalStorageUri.fsPath)
22-
await safeWriteJson(path.join(cacheDir, filename), data)
21+
await fs.writeFile(path.join(cacheDir, filename), JSON.stringify(data, null, 2))
2322
}
2423

2524
async function readModelEndpoints(key: string): Promise<ModelRecord | undefined> {

src/core/config/__tests__/importExport.test.ts

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { importSettings, exportSettings } from "../importExport"
1212
import { ProviderSettingsManager } from "../ProviderSettingsManager"
1313
import { ContextProxy } from "../ContextProxy"
1414
import { CustomModesManager } from "../CustomModesManager"
15-
import { safeWriteJson } from "../../../utils/safeWriteJson"
1615

1716
jest.mock("vscode", () => ({
1817
window: {
@@ -34,8 +33,6 @@ jest.mock("os", () => ({
3433
homedir: jest.fn(() => "/mock/home"),
3534
}))
3635

37-
jest.mock("../../../utils/safeWriteJson")
38-
3936
describe("importExport", () => {
4037
let mockProviderSettingsManager: jest.Mocked<ProviderSettingsManager>
4138
let mockContextProxy: jest.Mocked<ContextProxy>
@@ -375,10 +372,11 @@ describe("importExport", () => {
375372
expect(mockContextProxy.export).toHaveBeenCalled()
376373
expect(fs.mkdir).toHaveBeenCalledWith("/mock/path", { recursive: true })
377374

378-
expect(safeWriteJson).toHaveBeenCalledWith("/mock/path/roo-code-settings.json", {
379-
providerProfiles: mockProviderProfiles,
380-
globalSettings: mockGlobalSettings,
381-
})
375+
expect(fs.writeFile).toHaveBeenCalledWith(
376+
"/mock/path/roo-code-settings.json",
377+
JSON.stringify({ providerProfiles: mockProviderProfiles, globalSettings: mockGlobalSettings }, null, 2),
378+
"utf-8",
379+
)
382380
})
383381

384382
it("should include globalSettings when allowedMaxRequests is null", async () => {
@@ -407,10 +405,11 @@ describe("importExport", () => {
407405
contextProxy: mockContextProxy,
408406
})
409407

410-
expect(safeWriteJson).toHaveBeenCalledWith("/mock/path/roo-code-settings.json", {
411-
providerProfiles: mockProviderProfiles,
412-
globalSettings: mockGlobalSettings,
413-
})
408+
expect(fs.writeFile).toHaveBeenCalledWith(
409+
"/mock/path/roo-code-settings.json",
410+
JSON.stringify({ providerProfiles: mockProviderProfiles, globalSettings: mockGlobalSettings }, null, 2),
411+
"utf-8",
412+
)
414413
})
415414

416415
it("should handle errors during the export process", async () => {
@@ -425,8 +424,7 @@ describe("importExport", () => {
425424
})
426425

427426
mockContextProxy.export.mockResolvedValue({ mode: "code" })
428-
// Simulate an error during the safeWriteJson operation
429-
;(safeWriteJson as jest.Mock).mockRejectedValueOnce(new Error("Safe write error"))
427+
;(fs.writeFile as jest.Mock).mockRejectedValue(new Error("Write error"))
430428

431429
await exportSettings({
432430
providerSettingsManager: mockProviderSettingsManager,
@@ -437,10 +435,8 @@ describe("importExport", () => {
437435
expect(mockProviderSettingsManager.export).toHaveBeenCalled()
438436
expect(mockContextProxy.export).toHaveBeenCalled()
439437
expect(fs.mkdir).toHaveBeenCalledWith("/mock/path", { recursive: true })
440-
expect(safeWriteJson).toHaveBeenCalled() // safeWriteJson is called, but it will throw
438+
expect(fs.writeFile).toHaveBeenCalled()
441439
// The error is caught and the function exits silently.
442-
// Optionally, ensure no error message was shown if that's part of "silent"
443-
// expect(vscode.window.showErrorMessage).not.toHaveBeenCalled();
444440
})
445441

446442
it("should handle errors during directory creation", async () => {

src/core/config/importExport.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { safeWriteJson } from "../../utils/safeWriteJson"
21
import os from "os"
32
import * as path from "path"
43
import fs from "fs/promises"
@@ -117,6 +116,6 @@ export const exportSettings = async ({ providerSettingsManager, contextProxy }:
117116

118117
const dirname = path.dirname(uri.fsPath)
119118
await fs.mkdir(dirname, { recursive: true })
120-
await safeWriteJson(uri.fsPath, { providerProfiles, globalSettings })
119+
await fs.writeFile(uri.fsPath, JSON.stringify({ providerProfiles, globalSettings }, null, 2), "utf-8")
121120
} catch (e) {}
122121
}

src/core/context-tracking/FileContextTracker.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { safeWriteJson } from "../../utils/safeWriteJson"
21
import * as path from "path"
32
import * as vscode from "vscode"
43
import { getTaskDirectoryPath } from "../../utils/storage"
@@ -131,7 +130,7 @@ export class FileContextTracker {
131130
const globalStoragePath = this.getContextProxy()!.globalStorageUri.fsPath
132131
const taskDir = await getTaskDirectoryPath(globalStoragePath, taskId)
133132
const filePath = path.join(taskDir, GlobalFileNames.taskMetadata)
134-
await safeWriteJson(filePath, metadata)
133+
await fs.writeFile(filePath, JSON.stringify(metadata, null, 2))
135134
} catch (error) {
136135
console.error("Failed to save task metadata:", error)
137136
}

src/core/task-persistence/apiMessages.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { safeWriteJson } from "../../utils/safeWriteJson"
21
import * as path from "path"
32
import * as fs from "fs/promises"
43

@@ -47,5 +46,5 @@ export async function saveApiMessages({
4746
}) {
4847
const taskDir = await getTaskDirectoryPath(globalStoragePath, taskId)
4948
const filePath = path.join(taskDir, GlobalFileNames.apiConversationHistory)
50-
await safeWriteJson(filePath, messages)
49+
await fs.writeFile(filePath, JSON.stringify(messages))
5150
}

src/core/task-persistence/taskMessages.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { safeWriteJson } from "../../utils/safeWriteJson"
21
import * as path from "path"
32
import * as fs from "fs/promises"
43

@@ -38,5 +37,5 @@ export type SaveTaskMessagesOptions = {
3837
export async function saveTaskMessages({ messages, taskId, globalStoragePath }: SaveTaskMessagesOptions) {
3938
const taskDir = await getTaskDirectoryPath(globalStoragePath, taskId)
4039
const filePath = path.join(taskDir, GlobalFileNames.uiMessages)
41-
await safeWriteJson(filePath, messages)
40+
await fs.writeFile(filePath, JSON.stringify(messages))
4241
}

src/core/webview/__tests__/ClineProvider.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import { experimentDefault } from "../../../shared/experiments"
1313
import { setTtsEnabled } from "../../../utils/tts"
1414
import { ContextProxy } from "../../config/ContextProxy"
1515
import { Task, TaskOptions } from "../../task/Task"
16-
import { safeWriteJson } from "../../../utils/safeWriteJson"
1716

1817
import { ClineProvider } from "../ClineProvider"
1918

@@ -42,8 +41,6 @@ jest.mock("axios", () => ({
4241
post: jest.fn(),
4342
}))
4443

45-
jest.mock("../../../utils/safeWriteJson")
46-
4744
jest.mock(
4845
"@modelcontextprotocol/sdk/types.js",
4946
() => ({
@@ -2004,7 +2001,10 @@ describe("Project MCP Settings", () => {
20042001
)
20052002

20062003
// Verify file was created with default content
2007-
expect(safeWriteJson).toHaveBeenCalledWith(expect.stringContaining("mcp.json"), { mcpServers: {} })
2004+
expect(fs.writeFile).toHaveBeenCalledWith(
2005+
expect.stringContaining("mcp.json"),
2006+
JSON.stringify({ mcpServers: {} }, null, 2),
2007+
)
20082008
})
20092009

20102010
test("handles openProjectMcpSettings when workspace is not open", async () => {

0 commit comments

Comments
 (0)