From b182d740bd766ed0a08f1654a79d5cc65cd03c91 Mon Sep 17 00:00:00 2001 From: Mathis Date: Tue, 8 Oct 2024 11:30:26 +0200 Subject: [PATCH] Update file handling and error reporting in storage service Changed the file saving path from "files/" to "assets/" to unify storage structure. Improved error handling and logging in the file operations to aid in debugging. Additionally, streamlined database insertion and validation logic in the files service for better efficiency and readability. --- .../backend/src/app/files/files.controller.ts | 70 +++++++----- apps/backend/src/app/files/files.service.ts | 106 +++++++++--------- .../src/app/storage/storage.service.ts | 8 +- assets/.gitkeep | 0 4 files changed, 98 insertions(+), 86 deletions(-) create mode 100644 assets/.gitkeep diff --git a/apps/backend/src/app/files/files.controller.ts b/apps/backend/src/app/files/files.controller.ts index 69d9884..2190868 100644 --- a/apps/backend/src/app/files/files.controller.ts +++ b/apps/backend/src/app/files/files.controller.ts @@ -34,42 +34,52 @@ export class FilesController { }); req.on("end", async () => { - const _fileName = req.headers["file_name"] as string; - const _groupId = req.headers["group_id"] as string; - const _uploadedBy = req.headers["uploaded_by"] as string; - const _machineId = req.headers["machine_id"]; - const _isDocumentation = req.headers["is_documentation"] as string; - const _isRestricted = req.headers["is_restricted"] as string; - const _isAdmin = Boolean(req.headers["is_admin"] as string | boolean); + try { + console.log(fileBuffer); + const _fileName = req.headers["file_name"] as string; + const _groupId = req.headers["group_id"] as string; + const _uploadedBy = req.headers["uploaded_by"] as string; + const _machineId = req.headers["machine_id"]; + const _isDocumentation = req.headers["is_documentation"] as string; + const _isRestricted = req.headers["is_restricted"] as string; + const _isAdmin = Boolean(req.headers["is_admin"] as string | boolean); + console.log(_fileName, _groupId, _uploadedBy, _machineId, _isDocumentation, _isRestricted, _isAdmin); - // Vérifier que les en-têtes nécessaires sont présents - if (!_fileName || !_groupId || !_machineId) { - throw new BadRequestException("Header(s) manquant(s)"); + // Vérifier que les en-têtes nécessaires sont présents + if (!_fileName || !_groupId || !_machineId) { + throw new BadRequestException("Header(s) manquant(s)"); + } + const machineId = Array(_machineId); + + const Params = new Map() + .set("fileName", _fileName.toString()) + .set("groupId", Array(JSON.parse(_groupId.toString()))) + .set("uploadedBy", _uploadedBy.toString()) + .set("machineId", Array(JSON.parse(machineId.toString()))) + .set("isDocumentation", false) + .set("isRestricted", false); + + console.log(Params); + + //TODO Integrate a verification if the source is an admin, if that the case then it can define isDocumentation and isRestricted else throw in case of presence of those parameters. + if (_isAdmin) { + Params.set("isDocumentation", Boolean(_isDocumentation)); + Params.set("isRestricted", Boolean(_isRestricted)); + } + + return await this.filesService.save(fileBuffer, Params); + } catch (err) { + // @ts-ignore + return res.status(err.status || HttpStatus.INTERNAL_SERVER_ERROR).send(err) } - const machineId = Array(..._machineId); - - const Params = new Map() - .set("fileName", _fileName.toString()) - .set("groupId", _groupId.toString()) - .set("uploadedBy", _uploadedBy.toString()) - .set("machineId", Array(..._machineId)) - .set("isDocumentation", false) - .set("isRestricted", false); - - //TODO Integrate a verification if the source is an admin, if that the case then it can define isDocumentation and isRestricted else throw in case of presence of those parameters. - if (_isAdmin) { - Params.set("isDocumentation", Boolean(_isDocumentation)); - Params.set("isRestricted", Boolean(_isRestricted)); - } - - await this.filesService.save(fileBuffer, Params); - - return { message: "Fichier sauvegardé avec succès" }; }); req.on("error", (err) => { - throw new BadRequestException(err.message); + // @ts-ignore + return res.status(err.status || HttpStatus.INTERNAL_SERVER_ERROR).send(err) }); + + return; } @Get("find") diff --git a/apps/backend/src/app/files/files.service.ts b/apps/backend/src/app/files/files.service.ts index e49f2c4..5ac4783 100644 --- a/apps/backend/src/app/files/files.service.ts +++ b/apps/backend/src/app/files/files.service.ts @@ -9,9 +9,9 @@ import { FilesForMachinesTable, FilesGroupTable, FilesTable, - FilesTypeForMachine, - MachinesTable, -} from "apps/backend/src/app/db/schema"; + FilesTypeForMachine, FilesTypesTable, + MachinesTable +} from 'apps/backend/src/app/db/schema'; import { StorageService } from "apps/backend/src/app/storage/storage.service"; import { data } from "autoprefixer"; import { eq, ilike } from "drizzle-orm"; @@ -49,6 +49,7 @@ export class FilesService { "Multiples entries found in the database.\nInformation from the first row will be used.", ); const file = foundFiles[0]; + console.log(file); const fileBuffer = await this.storage.read( file.checksum, @@ -62,7 +63,7 @@ export class FilesService { ); const fileNameWithoutSpaces = file.fileName.replace(/\s/g, "_"); return new StreamableFile(fileBuffer, { - disposition: `attachment; filename="${fileNameWithoutSpaces}.${fileInformation.fileType[0].extension.toLowerCase()}"`, + disposition: `attachment; filename="${fileNameWithoutSpaces}.${fileInformation.fileType.extension.toLowerCase()}"`, }); } @@ -80,64 +81,73 @@ export class FilesService { //TODO save a file public async save(file: Buffer, data: Map) { - const _machineIds = Array.from(data.get("machineId") as string[]); - const machinesIds = new Set(); - console.log( - `Checking if machine with ID ${_machineIds} exist in the database...`, - ); - for (const machineId of _machineIds) { - const machineExists = await this.database - .use() - .select({ - uuid: MachinesTable.id, - }) - .from(MachinesTable) - .where(eq(MachinesTable.id, machineId)) - .prepare("checkMachineExists") - .execute(); + try { + const _machineIds = data.get("machineId").toString().split(","); - if (machineExists.length === 0) { - throw new NotFoundException(`Machine with ID "${machineId}" not found`); + const machinesIds = new Set(); + for (const machineId of _machineIds) { + console.log( + `Checking if machine with ID ${machineId} exist in the database...`, + ); + const machineExists = await this.database + .use() + .select({ + uuid: MachinesTable.id, + }) + .from(MachinesTable) + .where(eq(MachinesTable.id, machineId)) + .prepare("checkMachineExists") + .execute(); + + if (machineExists.length === 0) { + throw new NotFoundException(`Machine with ID "${machineId}" not found`); + } + + machinesIds.add(machineExists[0].uuid); } - machinesIds.add(machineExists[0].uuid); - } + const _group = data.get("groupId") as string; + // verify that the group exist in the database + const groupExists = await this.database + .use() + .select() + .from(FilesGroupTable) + .where(eq(FilesGroupTable.uuid, _group)) + .prepare("checkGroupExists") + .execute(); - const _group = data.get("groupId") as string; - // verify that the group exist in the database - const groupExists = await this.database - .use() - .select() - .from(FilesGroupTable) - .where(eq(FilesGroupTable.uuid, _group)) - .prepare("checkGroupExists") - .execute(); + if (groupExists.length === 0) { + throw new NotFoundException(`Group with ID "${_group}" not found`); + } - if (groupExists.length === 0) { - throw new NotFoundException(`Group with ID "${_group}" not found`); - } - - try { const saveResult = await this.storage.new( data.get("fileName") as string, file, _machineIds, Boolean(data.get("isDocumentation")), ); + console.log(saveResult); + const mimeId = await this.database.use() + .select() + .from(FilesTypesTable) + .where(eq(FilesTypesTable.mime, saveResult.fileType.mime)) + + const inserted = await this.database .use() .insert(FilesTable) .values({ fileName: data.get("fileName") as string, checksum: saveResult.fileChecksum, - extension: saveResult.fileType[0].extension, + extension: saveResult.fileType.extension, fileSize: saveResult.fileSize, - fileType: saveResult.fileType.mime, + fileType: mimeId[0].id, isRestricted: Boolean(data.get("isRestricted")), isDocumentation: Boolean(data.get("isDocumentation")), uploadedBy: data.get("uploadedBy") as string, }) .returning(); + console.log(inserted); for (const machineId of machinesIds) { //TODO insert a link betwen fileId and MachineIds[] @@ -149,20 +159,10 @@ export class FilesService { machineId: machineId, }); } - } catch (e) { - throw new InternalServerErrorException( - "It seems that the insertion in the database failed.", - { - cause: - process.env.NODE_ENV === "production" - ? "Internal server error" - : { - message: e.message, - stack: e.stack, - }, - description: `Nom de fichier : "${data.get("fileName")}" `, - }, - ); + + return inserted[0]; + } catch (err) { + throw err; } } } diff --git a/apps/backend/src/app/storage/storage.service.ts b/apps/backend/src/app/storage/storage.service.ts index 37f7c1f..e2baeee 100644 --- a/apps/backend/src/app/storage/storage.service.ts +++ b/apps/backend/src/app/storage/storage.service.ts @@ -34,7 +34,7 @@ export class StorageService { */ private async saveFile(fileName: string, file: Buffer): Promise { try { - await writeFile(join(process.cwd(), "files/", fileName), file, "utf8"); + await writeFile(join(process.cwd(), "assets/", fileName), file, "utf8"); } catch (err) { console.error(err); throw new InternalServerErrorException("File save failed !"); @@ -123,7 +123,7 @@ export class StorageService { */ private async getFile(fileName: string): Promise { try { - return await readFile(join(process.cwd(), "files/", fileName)); + return await readFile(join(process.cwd(), "assets/", fileName)); } catch (err) { throw new NotFoundException("File not found"); } @@ -245,9 +245,11 @@ export class StorageService { await this.saveFile(info.fileName, file); // All good we return data about the file to append it to the db. + console.log(`File "${info.fileName}" saved successfully.`); return info; } catch (err) { - throw new BadRequestException(err); + console.error(err); + throw err; } } } diff --git a/assets/.gitkeep b/assets/.gitkeep new file mode 100644 index 0000000..e69de29