Skip to content

Commit

Permalink
fix: atomic writes to preferences COMPASS-7270 COMPASS-7269 (#4920)
Browse files Browse the repository at this point in the history
  • Loading branch information
mabaasit authored Sep 27, 2023
1 parent c2cc547 commit 76f72d8
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 6 deletions.
63 changes: 63 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions packages/compass-preferences-model/src/storage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,23 @@ describe('storage', function () {
).to.deep.equal(getDefaultPreferences());
});

it('when invalid json is stored, it sets the defaults', async function () {
const storage = new StoragePreferences(tmpDir);

const preferencesFile = getPreferencesFile(tmpDir);
await fs.mkdir(getPreferencesFolder(tmpDir));
await fs.writeFile(preferencesFile, '{}}', 'utf-8');

// Ensure it exists
expect(async () => await fs.access(preferencesFile)).to.not.throw;

await storage.setup();

expect(
JSON.parse((await fs.readFile(preferencesFile)).toString())
).to.deep.equal(getDefaultPreferences());
});

it('updates preferences', async function () {
const storage = new StoragePreferences(tmpDir);
await storage.setup();
Expand Down
12 changes: 8 additions & 4 deletions packages/compass-preferences-model/src/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,15 @@ export class StoragePreferences extends BasePreferencesStorage {
try {
this.preferences = await this.readPreferences();
} catch (e) {
if ((e as any).code !== 'ENOENT') {
throw e;
if (
(e as any).code === 'ENOENT' || // First time user
e instanceof SyntaxError // Invalid json
) {
// Create the file for the first time
await this.userData.write(this.file, this.defaultPreferences);
return;
}
// Create the file for the first time
await this.userData.write(this.file, this.defaultPreferences);
throw e;
}
}

Expand Down
2 changes: 2 additions & 0 deletions packages/compass-user-data/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@types/chai": "^4.2.21",
"@types/mocha": "^9.0.0",
"@types/sinon-chai": "^3.2.5",
"@types/write-file-atomic": "^4.0.1",
"chai": "^4.3.6",
"depcheck": "^1.4.1",
"eslint": "^7.25.0",
Expand All @@ -67,6 +68,7 @@
"prettier": "^2.7.1",
"sinon": "^9.2.3",
"typescript": "^5.0.4",
"write-file-atomic": "^5.0.1",
"zod": "^3.22.2"
}
}
3 changes: 2 additions & 1 deletion packages/compass-user-data/src/user-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import path from 'path';
import { createLoggerAndTelemetry } from '@mongodb-js/compass-logging';
import { getStoragePath } from '@mongodb-js/compass-utils';
import type { z } from 'zod';
import writeFile from 'write-file-atomic';

const { log, mongoLogId } = createLoggerAndTelemetry('COMPASS-USER-STORAGE');

Expand Down Expand Up @@ -172,7 +173,7 @@ export class UserData<T extends z.Schema> {
const filepath = this.getFileName(id);
const absolutePath = await this.getFileAbsolutePath(filepath);
try {
await fs.writeFile(absolutePath, this.serialize(content), {
await writeFile(absolutePath, this.serialize(content), {
encoding: 'utf-8',
});
return true;
Expand Down
8 changes: 7 additions & 1 deletion packages/compass/src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,13 @@ async function main(): Promise<void> {
});
}

await CompassApplication.init(mode, globalPreferences);
try {
await CompassApplication.init(mode, globalPreferences);
} catch (e) {
await handleUncaughtException(e as Error);
await CompassApplication.runExitHandlers().finally(() => app.exit(1));
return;
}

if (mode === 'CLI') {
let exitCode = 0;
Expand Down

0 comments on commit 76f72d8

Please sign in to comment.