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.
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 |
| // 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.
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.
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
atomicallylibrary to the project.Testing Instructions
Test corruption before this PR changes:
trunkbranch (i.e. test the app before this change).npm start.writing fileare shown.appdata-v1.jsonfile is corrupted. The common error is that the JSON structure is broken.rsand 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 fileare shown.appdata-v1.jsonfile is corrupted. The common error is that the JSON structure is broken.rsand 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.jsonfile doesn't get corrupted.Note
The property
testwill 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