Skip to content

Commit 6f153f8

Browse files
authored
Recover from ENOENT due to missing parent directory when trusting notebook (#12913)
1 parent 2103c86 commit 6f153f8

File tree

1 file changed

+22
-4
lines changed

1 file changed

+22
-4
lines changed

src/client/datascience/interactive-ipynb/digestStorage.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,20 @@ export class DigestStorage implements IDigestStorage {
2626
public async saveDigest(uri: Uri, signature: string) {
2727
const fileLocation = await this.getFileLocation(uri);
2828
// Since the signature is a hex digest, the character 'z' is being used to delimit the start and end of a single digest
29-
await this.fs.appendFile(fileLocation, `z${signature}z\n`);
30-
if (!this.loggedFileLocations.has(fileLocation)) {
31-
traceInfo(`Wrote trust for ${uri.toString()} to ${fileLocation}`);
32-
this.loggedFileLocations.add(fileLocation);
29+
try {
30+
await this.saveDigestInner(uri, fileLocation, signature);
31+
} catch (err) {
32+
// The nbsignatures dir is only initialized on extension activation.
33+
// If the user deletes it to reset trust, the next attempt to trust
34+
// an untrusted notebook in the same session will fail because the parent
35+
// directory does not exist.
36+
if (isFileNotFoundError(err)) {
37+
// Gracefully recover from such errors by reinitializing directory and retrying
38+
await this.initDir();
39+
await this.saveDigestInner(uri, fileLocation, signature);
40+
} else {
41+
traceError(err);
42+
}
3343
}
3444
}
3545

@@ -46,6 +56,14 @@ export class DigestStorage implements IDigestStorage {
4656
}
4757
}
4858

59+
private async saveDigestInner(uri: Uri, fileLocation: string, signature: string) {
60+
await this.fs.appendFile(fileLocation, `z${signature}z\n`);
61+
if (!this.loggedFileLocations.has(fileLocation)) {
62+
traceInfo(`Wrote trust for ${uri.toString()} to ${fileLocation}`);
63+
this.loggedFileLocations.add(fileLocation);
64+
}
65+
}
66+
4967
private async getFileLocation(uri: Uri): Promise<string> {
5068
const normalizedName = os.platform() === 'win32' ? uri.fsPath.toLowerCase() : uri.fsPath;
5169
const hashedName = createHash('sha256').update(normalizedName).digest('hex');

0 commit comments

Comments
 (0)