mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
refactor: Make piping consistent
This commit is contained in:
@@ -7,7 +7,7 @@ import { RepresentationMetadata } from '../ldp/representation/RepresentationMeta
|
||||
import { TEXT_TURTLE } from './ContentTypes';
|
||||
import { LDP, RDF } from './UriConstants';
|
||||
import { toNamedNode } from './UriUtil';
|
||||
import { pipeStreamsAndErrors, pushQuad } from './Util';
|
||||
import { pipeSafe, pushQuad } from './Util';
|
||||
|
||||
export class MetadataController {
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ export class MetadataController {
|
||||
* @returns The Readable object.
|
||||
*/
|
||||
public serializeQuads(quads: Quad[]): Readable {
|
||||
return pipeStreamsAndErrors(streamifyArray(quads), new StreamWriter({ format: TEXT_TURTLE }));
|
||||
return pipeSafe(streamifyArray(quads), new StreamWriter({ format: TEXT_TURTLE }));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,6 +56,6 @@ export class MetadataController {
|
||||
* @returns A promise containing the array of quads.
|
||||
*/
|
||||
public async parseQuads(readable: Readable): Promise<Quad[]> {
|
||||
return await arrayifyStream(pipeStreamsAndErrors(readable, new StreamParser({ format: TEXT_TURTLE })));
|
||||
return await arrayifyStream(pipeSafe(readable, new StreamParser({ format: TEXT_TURTLE })));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,20 +59,26 @@ export const matchingMediaType = (mediaA: string, mediaB: string): boolean => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Pipes one stream into another.
|
||||
* Makes sure an error of the first stream gets passed to the second.
|
||||
* Pipes one stream into another and emits errors of the first stream with the second.
|
||||
* In case of an error in the first stream the second one will be destroyed with the given error.
|
||||
* @param readable - Initial readable stream.
|
||||
* @param destination - The destination for writing data.
|
||||
* @param mapError - Optional function that takes the error and converts it to a new error.
|
||||
*
|
||||
* @returns The destination stream.
|
||||
*/
|
||||
export const pipeStreamsAndErrors = <T extends Writable>(readable: NodeJS.ReadableStream, destination: T,
|
||||
export const pipeSafe = <T extends Writable>(readable: NodeJS.ReadableStream, destination: T,
|
||||
mapError?: (error: Error) => Error): T => {
|
||||
// Not using `stream.pipeline` since the result there only emits an error event if the last stream has the error
|
||||
readable.pipe(destination);
|
||||
readable.on('error', (error): boolean => {
|
||||
readable.on('error', (error): void => {
|
||||
logger.warn(`Piped stream errored with ${error.message}`);
|
||||
return destination.emit('error', mapError ? mapError(error) : error);
|
||||
|
||||
// From https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options :
|
||||
// "One important caveat is that if the Readable stream emits an error during processing, the Writable destination
|
||||
// is not closed automatically. If an error occurs, it will be necessary to manually close each stream
|
||||
// in order to prevent memory leaks."
|
||||
destination.destroy(mapError ? mapError(error) : error);
|
||||
});
|
||||
return destination;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user