fix: improve error message for folders

This commit is contained in:
tdurieux
2023-05-08 15:16:56 +02:00
parent 4f6c1d25fc
commit 027f14ffbc
6 changed files with 56 additions and 26 deletions

View File

@@ -2,7 +2,7 @@ import { join, basename } from "path";
import { Response } from "express";
import { Readable } from "stream";
import Repository from "./Repository";
import { Tree, TreeElement, TreeFile } from "./types";
import { FILE_TYPE, Tree, TreeElement, TreeFile } from "./types";
import storage from "./storage";
import config from "../config";
import {
@@ -175,8 +175,14 @@ export default class AnonymizedFile {
httpStatus: 403,
});
}
if (await storage.exists(this.originalCachePath)) {
const exist = await storage.exists(this.originalCachePath);
if (exist == FILE_TYPE.FILE) {
return storage.read(this.originalCachePath);
} else if (exist == FILE_TYPE.FOLDER) {
throw new AnonymousError("folder_not_supported", {
object: this,
httpStatus: 400,
});
}
return await this.repository.source?.getFileContent(this);
}
@@ -223,7 +229,7 @@ export default class AnonymizedFile {
// unable to get file size
console.error(error);
}
const anonymizer = new AnonymizeTransformer(this);
anonymizer.once("transform", (data) => {

View File

@@ -1,6 +1,13 @@
import { join } from "path";
import storage from "./storage";
import { RepositoryStatus, Source, Tree, TreeElement, TreeFile } from "./types";
import {
FILE_TYPE,
RepositoryStatus,
Source,
Tree,
TreeElement,
TreeFile,
} from "./types";
import { Readable } from "stream";
import User from "./User";
import GitHubStream from "./source/GitHubStream";
@@ -333,7 +340,9 @@ export default class Repository {
async removeCache() {
this.model.isReseted = true;
await this.model.save();
if (await storage.exists(this._model.repoId + "/")) {
if (
(await storage.exists(this._model.repoId + "/")) !== FILE_TYPE.NOT_FOUND
) {
return storage.rm(this._model.repoId + "/");
}
}

View File

@@ -8,7 +8,7 @@ import storage from "../storage";
import Repository from "../Repository";
import GitHubBase from "./GitHubBase";
import AnonymizedFile from "../AnonymizedFile";
import { RepositoryStatus, SourceBase } from "../types";
import { FILE_TYPE, RepositoryStatus, SourceBase } from "../types";
import AnonymousError from "../AnonymousError";
import { tryCatch } from "bullmq";
@@ -132,8 +132,14 @@ export default class GitHubDownload extends GitHubBase implements SourceBase {
}
async getFileContent(file: AnonymizedFile): Promise<Readable> {
if (await storage.exists(file.originalCachePath)) {
const exists = await storage.exists(file.originalCachePath);
if (exists === FILE_TYPE.FILE) {
return storage.read(file.originalCachePath);
} else if (exists === FILE_TYPE.FOLDER) {
throw new AnonymousError("folder_not_supported", {
httpStatus: 400,
object: file,
});
}
// will throw an error if the file is not in the repository
await file.originalPath();
@@ -145,7 +151,7 @@ export default class GitHubDownload extends GitHubBase implements SourceBase {
async getFiles() {
const folder = this.repository.originalCachePath;
if (!(await storage.exists(folder))) {
if ((await storage.exists(folder)) === FILE_TYPE.NOT_FOUND) {
await this.download();
}
return storage.listFiles(folder);

View File

@@ -1,4 +1,4 @@
import { SourceBase, StorageBase, Tree } from "../types";
import { FILE_TYPE, SourceBase, StorageBase, Tree } from "../types";
import config from "../../config";
import * as fs from "fs";
@@ -17,8 +17,15 @@ export default class FileSystem implements StorageBase {
constructor() {}
/** @override */
async exists(p: string): Promise<boolean> {
return fs.existsSync(join(config.FOLDER, p));
async exists(p: string): Promise<FILE_TYPE> {
try {
const stat = await fs.promises.stat(join(config.FOLDER, p));
if (stat.isDirectory()) return FILE_TYPE.FOLDER;
if (stat.isFile()) return FILE_TYPE.FILE;
} catch (_) {
// ignore file not found or not downloaded
}
return FILE_TYPE.NOT_FOUND;
}
/** @override */
@@ -49,11 +56,7 @@ export default class FileSystem implements StorageBase {
file?: AnonymizedFile,
source?: SourceBase
): Promise<void> {
if (!(await this.exists(dirname(p)))) {
await fs.promises.mkdir(dirname(join(config.FOLDER, p)), {
recursive: true,
});
}
await this.mk(dirname(p));
return fs.promises.writeFile(join(config.FOLDER, p), data);
}
@@ -67,7 +70,7 @@ export default class FileSystem implements StorageBase {
/** @override */
async mk(dir: string): Promise<void> {
if (!(await this.exists(dir)))
if ((await this.exists(dir)) === FILE_TYPE.NOT_FOUND)
fs.promises.mkdir(join(config.FOLDER, dir), { recursive: true });
}

View File

@@ -1,4 +1,4 @@
import { SourceBase, StorageBase, Tree, TreeFile } from "../types";
import { FILE_TYPE, SourceBase, StorageBase, Tree, TreeFile } from "../types";
import {
GetObjectCommand,
ListObjectsV2CommandOutput,
@@ -44,14 +44,12 @@ export default class S3Storage implements StorageBase {
}
/** @override */
async exists(path: string): Promise<boolean> {
async exists(path: string): Promise<FILE_TYPE> {
if (!config.S3_BUCKET) throw new Error("S3_BUCKET not set");
try {
await this.client().headObject({
Bucket: config.S3_BUCKET,
Key: path,
});
return true;
// if we can get the file info, it is a file
await this.fileInfo(path);
return FILE_TYPE.FILE;
} catch (err) {
// check if it is a directory
const data = await this.client().listObjectsV2({
@@ -59,7 +57,9 @@ export default class S3Storage implements StorageBase {
Prefix: path,
MaxKeys: 1,
});
return (data.Contents?.length || 0) > 0;
return (data.Contents?.length || 0) > 0
? FILE_TYPE.FOLDER
: FILE_TYPE.NOT_FOUND;
}
}

View File

@@ -32,6 +32,12 @@ export interface SourceBase {
export type Source = GitHubDownload | GitHubStream | Zip;
export enum FILE_TYPE {
FILE = "file",
FOLDER = "folder",
NOT_FOUND = "not_found",
}
export interface StorageBase {
/**
* The type of storage
@@ -42,7 +48,7 @@ export interface StorageBase {
* check if the path exists
* @param path the path to check
*/
exists(path: string): Promise<boolean>;
exists(path: string): Promise<FILE_TYPE>;
send(p: string, res: Response): Promise<void>;