'use strict';

const MemDuplex = require('./MemDuplex.js');


function _sendMemDuplexToResponse(memDuplexes, index, response, logger){
    if(memDuplexes[index] === undefined){
        return response.end();
    }
    const memDuplexOnCall = memDuplexes[index];
    memDuplexOnCall.on('data', chunk => {
        response.write(chunk);
    });
    memDuplexOnCall.on('error', () => {
        logger.error('error piping data from source');
        return response.end();
    });
    memDuplexOnCall.on('end', () => {
        return process.nextTick(_sendMemDuplexToResponse,
            memDuplexes, index + 1, response, logger);
    });
}

function _fillMemDuplex(memDuplexes, index, dataRetrievalFn, response, logger){
    return dataRetrievalFn(memDuplexes[index].location, logger,
        (err, readable) => {
        if(err){
            logger.error('failed to get full object', {
                error: err,
                method: '_fillMemDuplex',
            });
            return response.connection.destroy();
        }
        readable.pipe(memDuplexes[index]);
        if(memDuplexes[index + 2]){
            readable.on('end', () => {
                return process.nextTick(_fillMemDuplex, memDuplexes, index + 2,
                    dataRetrievalFn, response, logger);
            });
        }
        readable.on('error', () => {
            logger.error('error piping data from readable to memDuplex');
            return response.connection.destroy();
        });
    });
}

exports.readySetStream = function readySetStream(locations, dataRetrievalFn,
    response, logger) {
    if (!logger) {
        logger = console;
    }
    if (locations.length === 0) {
        return response.end();
    }
    const memDuplexes = locations.map((location) => {
        return new MemDuplex(location);
    });

    _sendMemDuplexToResponse(memDuplexes, 0, response, logger);
    _fillMemDuplex(memDuplexes, 0, dataRetrievalFn, response, logger);
    if (memDuplexes.length > 1){
        _fillMemDuplex(memDuplexes, 1, dataRetrievalFn, response, logger);
    }
}

@@ -108,16 +108,66 @@
 , index,
+ errorHandlerFn,%0A                                 
  respons
@@ -410,34 +410,35 @@
 all.on('error', 
-()
+err
  =%3E %7B%0A        lo
@@ -490,36 +490,34 @@
         
-return response.end(
+errorHandlerFn(err
 );%0A    %7D
@@ -650,16 +650,32 @@
 dex + 1,
+ errorHandlerFn,
  respons
@@ -749,32 +749,72 @@
 dataRetrievalFn,
+ errorHandlerFn,%0A                       
  response, logge
@@ -1092,36 +1092,26 @@
 urn 
-response.connection.destroy(
+errorHandlerFn(err
 );%0A 
@@ -1345,32 +1345,48 @@
 dataRetrievalFn,
+ errorHandlerFn,
  response, logge
@@ -1444,18 +1444,19 @@
 error', 
-()
+err
  =%3E %7B%0A  
@@ -1550,36 +1550,26 @@
 urn 
-response.connection.destroy(
+errorHandlerFn(err
 );%0A 
@@ -1683,24 +1683,40 @@
 onse, logger
+, errorHandlerFn
 ) %7B%0A    if (
@@ -1821,32 +1821,145 @@
 se.end();%0A    %7D%0A
+    if (errorHandlerFn === undefined) %7B%0A        errorHandlerFn = err =%3E %7B response.connection.destroy(); %7D%0A    %7D%0A
     const memDup
@@ -2089,16 +2089,61 @@
 exes, 0,
+ errorHandlerFn,%0A                            
  respons
@@ -2197,32 +2197,67 @@
 dataRetrievalFn,
+ errorHandlerFn,%0A                  
  response, logge
@@ -2348,16 +2348,55 @@
 ievalFn,
+ errorHandlerFn,%0A                      
  respons

Add custom stream error handling