-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid data corruption due to writing concurrently in the user data file #366
Conversation
Note that this won't cover the case of atomic writes.
try { | ||
await atomically.writeFile( filePath, asString, 'utf-8' ); | ||
} catch ( error ) { | ||
// Fall back to FS function in case the writing fails with EXDEV error. | ||
// This issue might happen on Windows when renaming a file. | ||
// Reference: https://github.com/sindresorhus/electron-store/issues/106 | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
if ( ( error as any )?.code === 'EXDEV' ) { | ||
await fs.promises.writeFile( filePath, asString, 'utf-8' ); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implementation is based on conf
package (used by electron-store
):
https://github.com/sindresorhus/conf/blob/608adb0c46fb1680ddbd9833043478367a64c120/source/index.ts#L456-L467
@wojtekn I've just noticed you added the label |
@fluiddot unrelated. I added that to ensure we won't merge this significant change until Monday's release so we can have more time to test it before the next release. |
Removing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Reference: https://github.com/sindresorhus/electron-store/issues/106 | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
if ( ( error as any )?.code === 'EXDEV' ) { | ||
await fs.promises.writeFile( filePath, asString, 'utf-8' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should move this await fallback to a separate try/catch. If the regular writeFile fails it will crash the app. I guess that will be captured by Sentry anyway, but maybe we can fail gracefully.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the failure should be handled by the caller. For instance, if there's a write error when creating a site, we should let the IPC handler catch the error and fail gracefully. WDYT?
Related to 6197-gh-Automattic/dotcom-forge and 6887-gh-Automattic/dotcom-forge.
Proposed Changes
atomically
library to the project.Testing Instructions
Test corruption before this PR changes:
trunk
branch (i.e. test the app before this change).npm start
.writing file
are shown.appdata-v1.json
file is corrupted. The common error is that the JSON structure is broken.rs
and press enter in the terminal to reload the app. Repeat steps 4, 5, and 6 until you encounter the issue.Corrupted data example:
Test this PR changes:
npm start
.writing file
are shown.appdata-v1.json
file is corrupted. The common error is that the JSON structure is broken.rs
and press enter in the terminal to reload the app. Repeat steps 4, 5 and 6 multiple times to ensure that content is not corrupted.appdata-v1.json
file doesn't get corrupted.Note
The property
test
will be appended to the user data file. It shouldn't impact the app, but it's recommended to remove it from the file after finishing testing.Pre-merge Checklist