Search code examples
node.jszipnode-archiver

Cant set headers after they are sent node.js


I am trying to combine multiple textfiles,convert them in a single zip file using zip archiver.

   exports.downloadFilesInZip = function(req, res, next) {

var respObj = {};
var file_names = [];
    var projectId = 111;
    var file_ids = 11111;
    console.log(projectId);
    db.getConnection(function (err, connection) {
        if (err) {
            debug(err);
            next(err);
        }
        else {
            var updateQuery = "select data from file_data where file_id IN (?)";
            console.log(updateQuery);
            connection.query(updateQuery,[file_ids], function (err, results) {
                console.log("inside" + updateQuery);

                if (err) {
                    connection.release();
                    console.log("error" + JSON.stringify(err));
                    debug(err);
                    next(err);
                }
                else {
                    async.eachSeries(results,function(item,loopCallBack){
                        var text = "";
                        console.log("hllllllll");
                        console.log(item.data);
                        console.log(JSON.parse(item.data));
                        document_text = JSON.parse(item.data);
                        console.log("dssddssdsdsdsdsd"+document_text);
                        for(var j=0; j < document_text.length ;j++)
                        {
                            text += document_text[j]['text'];
                        }

                        //file_names.push(convertStringToTextFile(text));
                        convertStringToTextFile(text,function(err,file_name){
                            if(err){
                                console.log(err);
                                loopCallBack(err);
                            }
                            else {
                                file_names.push(file_name);
                                loopCallBack();
                            }
                        })

                    },function(err){
                        if(err){
                            console.log(err);
                            next(err);
                        }
                        else {
                            var updateQuery = "select name from project where id in (?)";
                            console.log(updateQuery);
                            connection.query(updateQuery,[projectId], function (err, results) {
                                console.log("inside" + updateQuery);
                                connection.release();
                                if (err) {
                                    console.log("error" + JSON.stringify(err));
                                    debug(err);
                                    next(err);
                                }
                                else {
                                    var fileName_link = JSON.stringify(results[0].name);

                                    console.log("projectname"+fileName_link);
                                    convertTextFilesToZip(file_names,fileName_link, function (err, filename) {
                                        if (err) {
                                            console.log(err);
                                            next(err);
                                        }
                                        else {
                                            console.log("filename link" + filename);
                                            res.json({
                                                status: 0,
                                                file_link: filename
                                            });
                                        }
                                    });
                                }
                            });
                        }

                    });

                }
            });

        }
    });
}

}

convertStringToTextFile = function(text,cb){
var json_filename = 'tmp/file_'+uuid.v4().replace('-','')+'.txt';
fs.writeFile(json_filename, text , function (err) {
    if (err) {
        debug(err);
        cb(err);
    }
    else{
        cb(null,json_filename);
    }
});

};

convertTextFilesToZip = function(textFiles,file_link,cb){
console.log("textfiles"+textFiles);
var filename = 'reports/'+JSON.parse(file_link)+'_extractedText.zip';
var output = fs.createWriteStream(filename);

output.on('close', function() {
    console.log(zipArchive.pointer() + ' total bytes');
    console.log('archiver has been finalized and the output file descriptor has closed.');
});

zipArchive.on('error', function(err) {
    cb(err);
});

zipArchive.pipe(output);

zipArchive.bulk([
    { expand: true, src: textFiles }
]);

zipArchive.finalize();
cb(null,filename);


}

It works okay the first time and after that it throws this error.I have checked other posts in which res is returned twice but i couldn't find it.It says that can't set headers after they are sent.I think the problem is in the convertTextFilesToZip function but i cant seem to pinpoint the exact location which is generating the error.ANy help is appreciated.

  Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:350:11)
at ServerResponse.header     (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/express/lib/response.js:700:10)
at ServerResponse.send (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/express/lib/response.js:154:12)
at fn (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/express/lib/response.js:934:10)
at View.exports.renderFile [as engine] (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/jade/lib/index.js:374:12)
at View.render (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/express/lib/view.js:93:8)
at EventEmitter.app.render (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/express/lib/application.js:566:10)
at ServerResponse.res.render (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/express/lib/response.js:938:7)
at /Users/zeeshandar/Desktop/Agreements_info/agreements_info/app.js:207:13
at Layer.handle_error (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/express/li b/router/layer.js:58:5)

Solution

  • Making my comment into an answer since it appears to have led to the solution.

    The variable zipArchive is not initialized in convertTextFilesToZip() therefore you are reusing that variable from one function call to the next and that seems unlikely to be the right implementation.

    Also, I would expect your method calls to zipArchive to be asynchronous and it doesn't look like your are coding for that since the callback is called before you have any sort of completion notification.