Fix workspace folder deletion error (#13270)

context : workspace folder deletion throws error when folder does not
exist (in case, workspace users have not upload any files (profil pic,
workflows, attachments, ...))
-> sentry errors :
https://twenty-v7.sentry.io/issues/6565008010/?referrer=github_integration

solution : check folder existence before deleting

test local and s3 storage : 
- create a workspace and delete workspace
- create a workspace, add an attachment and delete workspace

closes : https://github.com/twentyhq/twenty/issues/10745
closes : https://github.com/twentyhq/twenty/issues/12299
This commit is contained in:
Etienne
2025-07-17 23:01:02 +02:00
committed by GitHub
parent abd9f8205b
commit 21fb68b9e2
5 changed files with 40 additions and 0 deletions

View File

@ -25,4 +25,5 @@ export interface StorageDriver {
folderPath: string;
filename: string;
}): Promise<boolean>;
checkFolderExists(folderPath: string): Promise<boolean>;
}

View File

@ -175,4 +175,10 @@ export class LocalDriver implements StorageDriver {
return existsSync(filePath);
}
async checkFolderExists(folderPath: string): Promise<boolean> {
const folderFullPath = join(this.options.storagePath, folderPath);
return existsSync(folderFullPath);
}
}

View File

@ -417,4 +417,24 @@ export class S3Driver implements StorageDriver {
return true;
}
async checkFolderExists(folderPath: string): Promise<boolean> {
try {
const listCommand = new ListObjectsV2Command({
Bucket: this.bucketName,
Prefix: folderPath,
MaxKeys: 1,
});
const result = await this.s3Client.send(listCommand);
return (result.Contents && result.Contents.length > 0) || false;
} catch (error) {
if (error instanceof NotFound) {
return false;
}
throw error;
}
}
}

View File

@ -70,4 +70,10 @@ export class FileStorageService implements StorageDriver {
return driver.checkFileExists(params);
}
checkFolderExists(folderPath: string): Promise<boolean> {
const driver = this.fileStorageDriverFactory.getCurrentDriver();
return driver.checkFolderExists(folderPath);
}
}

View File

@ -93,6 +93,13 @@ export class FileService {
async deleteWorkspaceFolder(workspaceId: string) {
const workspaceFolderPath = `workspace-${workspaceId}`;
const isWorkspaceFolderFound =
await this.fileStorageService.checkFolderExists(workspaceFolderPath);
if (!isWorkspaceFolderFound) {
return;
}
return await this.fileStorageService.delete({
folderPath: workspaceFolderPath,
});