Improved error catching for streams

This commit is contained in:
subnub
2020-04-19 17:06:16 -04:00
parent e18ae1eee1
commit d4141a9dcc
7 changed files with 142 additions and 67 deletions
@@ -69,7 +69,9 @@ class FileSystemService implements ChunkInterface {
const fileWriteStream = fs.createWriteStream(metadata.filePath);
await awaitUploadStreamFS(file.pipe(cipher), fileWriteStream, req, metadata.filePath);
const totalStreamsToErrorCatch = [file, cipher, fileWriteStream];
await awaitUploadStreamFS(file.pipe(cipher), fileWriteStream, req, metadata.filePath, totalStreamsToErrorCatch);
const date = new Date();
const encryptedFileSize = await getFileSize(metadata.filePath);
@@ -124,7 +126,9 @@ class FileSystemService implements ChunkInterface {
res.set('Content-Disposition', 'attachment; filename="' + currentFile.filename + '"');
res.set('Content-Length', currentFile.metadata.size.toString());
await awaitStream(readStream.pipe(decipher), res);
const allStreamsToErrorCatch = [readStream, decipher];
await awaitStream(readStream.pipe(decipher), res, allStreamsToErrorCatch);
}
getThumbnail = async(user: UserInterface, id: string) => {
@@ -148,7 +152,9 @@ class FileSystemService implements ChunkInterface {
const readStream = fs.createReadStream(thumbnail.path!);
const bufferData = await streamToBuffer(readStream.pipe(decipher));
const allStreamsToErrorCatch = [readStream, decipher];
const bufferData = await streamToBuffer(readStream.pipe(decipher), allStreamsToErrorCatch);
return bufferData;
@@ -177,8 +183,10 @@ class FileSystemService implements ChunkInterface {
res.set('Content-Disposition', 'attachment; filename="' + file.filename + '"');
res.set('Content-Length', file.metadata.size.toString());
const allStreamsToErrorCatch = [readStream, decipher];
console.log("Sending Full Thumbnail...")
await awaitStream(readStream.pipe(decipher), res);
await awaitStream(readStream.pipe(decipher), res, allStreamsToErrorCatch);
console.log("Full thumbnail sent");
}
@@ -221,7 +229,9 @@ class FileSystemService implements ChunkInterface {
res.writeHead(206, head);
await awaitStream(readStream.pipe(decipher), res);
const allStreamsToErrorCatch = [readStream, decipher];
await awaitStream(readStream.pipe(decipher), res, allStreamsToErrorCatch);
}
getPublicDownload = async(fileID: string, tempToken: any, res: Response) => {
@@ -250,7 +260,9 @@ class FileSystemService implements ChunkInterface {
res.set('Content-Disposition', 'attachment; filename="' + file.filename + '"');
res.set('Content-Length', file.metadata.size.toString());
await awaitStream(readStream.pipe(decipher), res);
const allStreamsToErrorCatch = [readStream, decipher];
await awaitStream(readStream.pipe(decipher), res, allStreamsToErrorCatch);
if (file.metadata.linkType === "one") {
console.log("removing public link");
+16 -5
View File
@@ -71,7 +71,9 @@ class MongoService implements ChunkInterface {
bucketStream = bucket.openUploadStream(filename, {metadata});
const finishedFile = await awaitUploadStream(file.pipe(cipher), bucketStream, req) as FileInterface;
const allStreamsToErrorCatch = [file, cipher, bucketStream];
const finishedFile = await awaitUploadStream(file.pipe(cipher), bucketStream, req, allStreamsToErrorCatch) as FileInterface;
const imageCheck = imageChecker(filename);
@@ -110,7 +112,9 @@ class MongoService implements ChunkInterface {
res.set('Content-Disposition', 'attachment; filename="' + currentFile.filename + '"');
res.set('Content-Length', currentFile.metadata.size.toString());
await awaitStream(readStream.pipe(decipher), res);
const allStreamsToErrorCatch = [readStream, decipher];
await awaitStream(readStream.pipe(decipher), res, allStreamsToErrorCatch);
}
getThumbnail = async(user: UserInterface, id: string) => {
@@ -164,7 +168,10 @@ class MongoService implements ChunkInterface {
res.set('Content-Length', file.metadata.size.toString());
console.log("Sending Full Thumbnail...")
await awaitStream(readStream.pipe(decipher), res);
const allStreamsToErrorCatch = [readStream, decipher];
await awaitStream(readStream.pipe(decipher), res, allStreamsToErrorCatch);
console.log("Full thumbnail sent");
}
@@ -196,7 +203,9 @@ class MongoService implements ChunkInterface {
res.set('Content-Disposition', 'attachment; filename="' + file.filename + '"');
res.set('Content-Length', file.metadata.size.toString());
await awaitStream(readStream.pipe(decipher), res);
const allStreamsToErrorCatch = [readStream, decipher];
await awaitStream(readStream.pipe(decipher), res, allStreamsToErrorCatch);
if (file.metadata.linkType === "one") {
console.log("removing public link");
@@ -247,7 +256,9 @@ class MongoService implements ChunkInterface {
res.writeHead(206, head);
await awaitStream(readStream.pipe(decipher), res);
const allStreamsToErrorCatch = [readStream, decipher];
await awaitStream(readStream.pipe(decipher), res, allStreamsToErrorCatch);
}
deleteFile = async(userID: string, fileID: string) => {
+15 -5
View File
@@ -125,7 +125,9 @@ class S3Service implements ChunkInterface {
const s3ReadStream = s3.getObject(params).createReadStream();
await awaitStream(s3ReadStream.pipe(decipher), res);
const allStreamsToErrorCatch = [s3ReadStream, decipher];
await awaitStream(s3ReadStream.pipe(decipher), res, allStreamsToErrorCatch);
}
@@ -167,7 +169,9 @@ class S3Service implements ChunkInterface {
res.writeHead(206, head);
await awaitStream(s3ReadStream.pipe(decipher), res);
const allStreamsToErrorCatch = [s3ReadStream, decipher];
await awaitStream(s3ReadStream.pipe(decipher), res, allStreamsToErrorCatch);
}
@@ -194,7 +198,9 @@ class S3Service implements ChunkInterface {
const readStream = s3.getObject(params).createReadStream();
const bufferData = await streamToBuffer(readStream.pipe(decipher));
const allStreamsToErrorCatch = [readStream, decipher];
const bufferData = await streamToBuffer(readStream.pipe(decipher), allStreamsToErrorCatch);
return bufferData;
}
@@ -224,8 +230,10 @@ class S3Service implements ChunkInterface {
res.set('Content-Disposition', 'attachment; filename="' + file.filename + '"');
res.set('Content-Length', file.metadata.size.toString());
const allStreamsToErrorCatch = [readStream, decipher];
console.log("Sending Full Thumbnail...")
await awaitStream(readStream.pipe(decipher), res);
await awaitStream(readStream.pipe(decipher), res, allStreamsToErrorCatch);
console.log("Full thumbnail sent");
}
@@ -257,7 +265,9 @@ class S3Service implements ChunkInterface {
res.set('Content-Disposition', 'attachment; filename="' + file.filename + '"');
res.set('Content-Length', file.metadata.size.toString());
await awaitStream(readStream.pipe(decipher), res);
const allStreamsToErrorCatch = [readStream, decipher];
await awaitStream(readStream.pipe(decipher), res, allStreamsToErrorCatch);
if (file.metadata.linkType === "one") {
console.log("removing public link");
@@ -1,21 +1,17 @@
const awaitStream = <T>(inputSteam: any, outputStream: any) => {
const awaitStream = <T>(inputSteam: any, outputStream: any, allStreamsToErrorCatch: any[]) => {
return new Promise<T>((resolve, reject) => {
inputSteam.on("error", (e: Error) => {
reject({
message: "Await Stream Input Error",
code: 500,
error: e
})
})
allStreamsToErrorCatch.forEach((currentStream: any) => {
outputStream.on("error", (e: Error) => {
reject({
message: "Await Stream Output Error",
code: 500,
error: e
currentStream.on("error", (e: Error) => {
reject({
message: "Await Stream Input Error",
code: 500,
error: e
})
})
})
inputSteam.pipe(outputStream).on("finish", (data: T) => {
@@ -1,31 +1,45 @@
import removeChunks from "../../FileService/utils/removeChunks";
import {Request} from "express"
const awaitUploadStream = <T>(inputSteam: any, outputStream: any, req: Request) => {
const awaitUploadStream = <T>(inputSteam: any, outputStream: any, req: Request, allStreamsToErrorCatch: any[]) => {
return new Promise<T>((resolve, reject) => {
inputSteam.on("error", (e: Error) => {
allStreamsToErrorCatch.forEach((currentStream: any) => {
removeChunks(outputStream);
currentStream.on("error", (e: Error) => {
removeChunks(outputStream);
reject({
message: "Await Stream Input Error",
code: 500,
error: e
})
})
})
// inputSteam.on("error", (e: Error) => {
// removeChunks(outputStream);
reject({
message: "Await Stream Input Error",
code: 500,
error: e
})
})
// reject({
// message: "Await Stream Input Error",
// code: 500,
// error: e
// })
// })
outputStream.on("error", (e: Error) => {
// outputStream.on("error", (e: Error) => {
removeChunks(outputStream);
// removeChunks(outputStream);
reject({
message: "Await Stream Output Error",
code: 500,
error: e
})
})
// reject({
// message: "Await Stream Output Error",
// code: 500,
// error: e
// })
// })
req.on("aborted", () => {
@@ -9,6 +9,7 @@ export const removeChunksFS = (path: string) => {
if (err) {
console.log("Could not remove fs file", err);
resolve();
}
console.log("File Removed");
@@ -17,31 +18,45 @@ export const removeChunksFS = (path: string) => {
})
}
const awaitUploadStream = <T>(inputSteam: any, outputStream: any, req: Request, path: string) => {
const awaitUploadStream = <T>(inputSteam: any, outputStream: any, req: Request, path: string, allStreamsToCatchError: any[]) => {
return new Promise<T>((resolve, reject) => {
allStreamsToCatchError.forEach((currentStream: any) => {
inputSteam.on("error", (e: Error) => {
currentStream.on("error", (e: Error) => {
removeChunksFS(path);
removeChunksFS(path);
reject({
message: "Await Stream Input Error",
code: 500,
error: e
reject({
message: "Await Stream Input Error",
code: 500,
error: e
})
})
})
outputStream.on("error", (e: Error) => {
// inputSteam.on("error", (e: Error) => {
removeChunksFS(path);
// removeChunksFS(path);
// reject({
// message: "Await Stream Input Error",
// code: 500,
// error: e
// })
// })
reject({
message: "Await Stream Output Error",
code: 500,
error: e
})
})
// outputStream.on("error", (e: Error) => {
// removeChunksFS(path);
// reject({
// message: "Await Stream Output Error",
// code: 500,
// error: e
// })
// })
req.on("aborted", () => {
+23 -6
View File
@@ -1,10 +1,27 @@
const streamToBuffer = (stream: any) => {
const chunks: any[] = []
return new Promise<Buffer>((resolve, reject) => {
stream.on('data', (chunk: any) => chunks.push(chunk))
stream.on('error', reject)
stream.on('end', () => resolve(Buffer.concat(chunks)))
const streamToBuffer = (stream: any, allStreamsToErrorCatch: any[]) => {
const chunks: any[] = []
return new Promise<Buffer>((resolve, reject) => {
allStreamsToErrorCatch.forEach((currentStream) => {
currentStream.on("error", (e: Error) => {
console.log("Stream To Buffer Error", e);
reject({
message: "stream to buffer error",
code: 500,
error: e
})
})
})
stream.on('data', (chunk: any) => chunks.push(chunk));
stream.on('error', reject);
stream.on('end', () => resolve(Buffer.concat(chunks)));
})
}
export default streamToBuffer;