nodejs throw er; // Unhandled 'error' event - node.js

I made following, to play a bit around with node.js.
The files in the folder zipfiles are zipped accordingly and everything seems to work.
But I got an error on the cmd and I don't know where it comes from or how to solve it.
events.js:72
throw er; // Unhandled 'error' event
^
Error: write after end
at writeAfterEnd (_stream_writable.js:130:12)
at Gzip.Writable.write (_stream_writable.js:178:5)
at write (_stream_readable.js:583:24)
at flow (_stream_readable.js:592:7)
at ReadStream.pipeOnReadable (_stream_readable.js:624:5)
at ReadStream.EventEmitter.emit (events.js:92:17)
at emitReadable_ (_stream_readable.js:408:10)
at emitReadable (_stream_readable.js:404:5)
at readableAddChunk (_stream_readable.js:165:9)
at ReadStream.Readable.push (_stream_readable.js:127:10)
Here's my script:
var zlib = require('zlib');
var gzip = zlib.createGzip();
var fs = require('fs');
var zip = {
zipAll: function(dir){
//files to zip
fs.readdir(dir, function(err, data){
if(err) throw(err);
var arrayValue = data.toString().split(',');
//files with .gz at the end, needs to be excluded
for(var i=0; i<arrayValue.length; i+=1){
console.log("Zipping following files: " + arrayValue[i]);
var input = fs.createReadStream('zipfiles/' + arrayValue[i]);
var output = fs.createWriteStream('zipfiles/input'+[i]+'.txt'+'.gz');
input.pipe(gzip).pipe(output);
}
});
}
};
zip.zipAll('zipfiles');
Thanks

The Gzip object is a bit wonky (afaik undocumented) to reuse for multiple files. The easiest way to fix your problem is to simply use a separate gzip object per file to compress, something like;
for(var i=0; i<arrayValue.length; i+=1){
console.log("Zipping following files: " + arrayValue[i]);
var input = fs.createReadStream('zipfiles/' + arrayValue[i]);
var output = fs.createWriteStream('zipfiles/input'+[i]+'.txt'+'.gz');
input.pipe(zlib.createGzip()).pipe(output);
}

Related

Error: stream.push() after EOF

Playing with node steams
This code reads from index.js and writes to indexCopy.js - kind of file copy.
Target file got created, but during execution exception is thrown:
node index.js
events.js:183
throw er; // Unhandled 'error' event
^
Error: stream.push() after EOF
at readableAddChunk (_stream_readable.js:240:30)
at MyStream.Readable.push (_stream_readable.js:208:10)
at ReadStream.f.on (C:\Node\index.js:16:28)
at emitOne (events.js:116:13)
at ReadStream.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at ReadStream.Readable.push (_stream_readable.js:208:10)
at fs.read (fs.js:2042:12)
at FSReqWrap.wrapper [as oncomplete] (fs.js:658:17)
C:\Node>
This is code:
var util = require('util');
var stream = require('stream');
var fs = require('fs');
var MyStream = function(){
stream.Readable.call(this)
}
util.inherits(MyStream,stream.Readable);
MyStream.prototype._read = function(d){
f = fs.createReadStream("index.js");
f.on('data',(d)=>{this.push(d)});
f.on('end',()=>{this.push(null)}); //when file finished need to close stream
}
var f = fs.createWriteStream("indexCopy.js")
var myStream = new MyStream()
myStream.pipe(f);
I tried to call this.push(null) in 'data' event, in that case even target file is not created and code fails with the exception.
I realize that copy file should be done easier with pipe() function - I am just experimenting/learning.
What is wrong with my approach?
You don't want the f = fs.createReadStream("index.js") line inside the _read method -- _read gets called repeatedly so you're creating multiple read streams. Put that in your constructor instead.
function MyStream () {
stream.Readable.call(this);
this.source = fs.createReadStream("index.js");
this.haveBound = false;
}
MyStream.prototype._read = function () {
if (this.haveBound) return; // Don't bind to events repeatedly
this.haveBound = true;
this.source.on("data", d => this.push(d));
this.source.on("end", () => this.push(null));
};
This is awkward though. Streams are meant to be pipe'ed.

Nodejs illegal operation on a directory

Im trying to compile a folder of markdown files into a single PDF with markdown-pdf NPM package.
I have a simple script to do the job:
var mpdf = require('markdown-pdf');
var fs = require('fs');
var mDocs = fs.readdirSync('./understandinges6/manuscript/');
mDocs = mDocs.map(function(d) { return 'understandinges6/manuscript/' + d });
var Book = 'understandinges6.pdf';
mpdf().concat.from(mDocs).to(Book, function() {
console.log("Created", Book);
});
But when i execute the script, this error appears:
events.js:154
throw er; // Unhandled 'error' event
^
Error: EISDIR: illegal operation on a directory, read
at Error (native)
It's weird because i'm in my home folder with the respective permissions. I'm specifying the output folder/file in the script and just reading with fs.readdirSync.
Any idea about this?
mDocs = mDocs.map(function(d) { return 'understandinges6/manuscript/' + d }); you forgot to add "./". Rewrite to mDocs = mDocs.map(function(d) { return './understandinges6/manuscript/' + d });
Cool, i get the problem here:
In the manuscripts/ folder are a images/ sub-folder with some png's. When the scripts tryed to read and transform images/ from .md to .pdf the error was fired.
Here is the array with the images/ inside:
[ 'understandinges6/manuscript/00-Introduction.md',
'understandinges6/manuscript/01-Block-Bindings.md',
'understandinges6/manuscript/02-Strings-and-Regular-Expressions.md',
'understandinges6/manuscript/03-Functions.md',
'understandinges6/manuscript/04-Objects.md',
'understandinges6/manuscript/05-Destructuring.md',
'understandinges6/manuscript/06-Symbols.md',
'understandinges6/manuscript/07-Sets-And-Maps.md',
'understandinges6/manuscript/08-Iterators-And-Generators.md',
'understandinges6/manuscript/09-Classes.md',
'understandinges6/manuscript/10-Arrays.md',
'understandinges6/manuscript/11-Promises.md',
'understandinges6/manuscript/12-Proxies-and-Reflection.md',
'understandinges6/manuscript/13-Modules.md',
'understandinges6/manuscript/A-Other-Changes.md',
'understandinges6/manuscript/B-ECMAScript-7.md',
'understandinges6/manuscript/Book.txt',
'understandinges6/manuscript/images' ]
Solution? Just pop() the mDocs array (now just docs):
var mpdf = require('markdown-pdf');
var fs = require('fs');
var mDocs = fs.readdirSync('understandinges6/manuscript/');
var docs = mDocs.map(function(d) { return 'understandinges6/manuscript/' + d });
docs.pop();
var Book = 'understandinges6.pdf';
mpdf().concat.from(docs).to(Book, function() {
console.log("Created", Book);
});

Unhandled 'error' event when extracting zip file with nodejs

I want to download a zip file and extract it with nodejs. This is what I have done so far:
var fs = require('fs');
var wget = require('wget-improved');
var filesizeHumanReadable = require('filesize');
var unzip = require('unzip');
var downloadCSS = function() {
var src = 'http://7-zip.org/a/7za920.zip';
var output = '/tmp/7z.zip';
var options = {};
var download = wget.download(src, output, options);
download.on('error', function(err) {
console.log(err);
});
download.on('start', function(fileSize) {
console.log(filesizeHumanReadable(fileSize));
});
download.on('end', function(outputMessage) {
console.log(outputMessage);
console.log(output);
fs.createReadStream(output).pipe(unzip.Extract({ path: '/tmp/' }));
});
download.on('progress', function(progress) {
// code to show progress bar
});
}
The error message I get when running it:
mles-MacBook-Pro:test-api mles$ node index.js
375.83 KB
Finished writing to disk
/tmp/7z.zip
events.js:85
throw er; // Unhandled 'error' event
^
Error: EPERM, unlink '/tmp'
at Error (native)
Now I'm a bit baffled how to handle the error event and what my actual error is?
Does the process have enough permission to write to /tmp? Does /tmp already have some files?
Because unlink is a node.js function to delete directories. Apparently, unzip.Extract calls it. So, unlink fails if the folder isn't empty (in your case /tmp).
Setting the unzip location to a specific directory fixes it
fs.createReadStream(output).pipe(unzip.Extract({ path: '/tmp/7zip' }));
I'm marking mostruash answer as correct since he brought me on the right track.

How to pipe image from request to pdfkit in node.js?

First off, I am a total newbie both to Javascript and Node.js, so sorry if my question is stupid.
I am trying to scrape text and images off a website and export it to a pdf using request, cheerio and pdfkit, but I'm having problems.
I am able to scrape the images and save them locally using this:
var $ = cheerio.load(body);
$("#mediatab1 img").each(function(){
var image= 'http://WWW.WEBSITE.no' + $(this).attr('src');
images.push(image);
});
for(var i = 0; i < images.length; i++){
request(images[i]).pipe(fs.createWriteStream('images/' + i + '.jpg')); }
BUT! Here's the problem:
1. INTENT: When I try to write the files to the pdf using
doc.image('images/0.jpg');
all I get is
Error: Unknown image format.
at Function.PDFImage.open (C:\nodejs\node_modules\pdfkit\js\im
age.js:41:15)
at PDFDocument.module.exports.image (C:\nodejs\node_modules\pd
fkit\js\mixins\images.js:27:26)
at Request._callback (C:\nodejs\prosjekt.js:29:6)
at Request.self.callback (C:\nodejs\node_modules\request\reque
st.js:344:22)
at Request.emit (events.js:98:17)
at Request.<anonymous> (C:\nodejs\node_modules\request\request
.js:1239:14)
at Request.emit (events.js:117:20)
at IncomingMessage.<anonymous> (C:\nodejs\node_modules\request
\request.js:1187:12)
at IncomingMessage.emit (events.js:117:20)
at _stream_readable.js:944:16
0.jpg is 0 bytes, so I suspect there is a timing issue here?
2. INTENT
I tried to use .pipe instead of saving locally:
request(images[i]).pipe(doc.image(images[0]));
But all I get is:
"Error: ENOENT, no such file or directory 'C:\nodejs\http:\www.WEBSITE.no\Common\Tools\ImageScaler.ashx?id=c7d73548-8198-4bd1-867d-33fc0dfe73d1&h=4
13'
Any idea how to fix this or to solve the problem in any other way?
Here's the whole script:
var request = require('request'),
cheerio = require('cheerio'),
PDFDocument = require('pdfkit'),
doc = new PDFDocument,
fs = require('fs'),
prompt = require('prompt');
bilder = [];
prompt.start();
prompt.get(['prosjekturl'], function (err, result) {
request({url: 'http://www.WEBSITE.no/no/Prosjekter/Prosjekt/?pid=' + result.prosjekturl, encoding:null}, function(err, resp, body){
if(!err && resp.statusCode == 200){
// console.log(body);
var $ = cheerio.load(body);
$("#mediatab1 img").each(function(){
var bilde = 'http://www.WEBSITE.no' + $(this).attr('src');
bilder.push(bilde);
});
console.log(bilder);
for(var i = 0; i < bilder.length; i++){
request(bilder[i]).pipe(fs.createWriteStream('images/' + i + '.jpg'));
}
$("#MiddleRightContainer h1").each(function(){
var tittel = $(this).text();
console.log(tittel);
doc.pipe(fs.createWriteStream('pdf/output.pdf'));
doc.font('fonts/FONT-Regular.ttf');
doc.fontSize(32);
doc.text(tittel);
});
$("#MiddleRightContainer .user-content p").each(function(){
var tekst = $(this).text();
console.log(tekst);
doc.pipe(fs.createWriteStream('pdf/output.pdf'));
doc.fontSize(12);
doc.text(tekst);
});
$("#RightSidebar div.box2").each(function(){
var fakta = $(this).text();
console.log(fakta);
});
}
doc.end();
});
});
From docs:
"PDFKit supports the JPEG and PNG formats"
Here you can see it's checking .jpeg and .png extensions. Yours is a .jpg file. I've had trouble with this a few times and this has fixed my issue.
When it comes to the file loading I suspect that the windows paths can be a problem. Try and use node.js built-in path resolution: https://nodejs.org/api/path.html
When it comes to request and loading images it should not be more than:
request({
url: url,
// Prevents Request from converting response to string
encoding: null
}, function (err, response, body) {
doc.image(body)
})
Hope it helps some.

node.js tar module, 'entry' readable stream

how should I use 'entry' readable stream from tar module to pipe - npmsj.org their content without get a stream error in pipe?
this is to get hint for stream-adventure - github last exercise.
I'm not looking for a answer. but a hint or advice.
Here is my code:
var zlib = require('zlib');
var tar = require('tar');
var crypto = require('crypto');
var through = require('through');
var unzip = zlib.createGunzip();
var parser = tar.Parse();
var stream = process.stdin.pipe(crypto.createDecipher(process.argv[2], process.argv[3])).pipe(unzip);
var md5 = crypto.createHash('md5', { encoding: 'hex' });
parser.on('entry', function(entry) {
if (entry.type === 'File') {
entry.pipe(md5).pipe(process.stdout);
console.log(entry.path);
}
});
unzip.pipe(parser);
here is the output:
$> stream-adventure run app
97911dcc607865d621029f6f927c7851
stream.js:94
throw er; // Unhandled stream error in pipe.
^
Error: write after end
at writeAfterEnd (_stream_writable.js:130:12)
at Hash.Writable.write (_stream_writable.js:178:5)
at Entry.ondata (stream.js:51:26)
at Entry.EventEmitter.emit (events.js:117:20)
at Entry._read (/home/n0t/stream-adventure/secretz/node_modules/tar/lib/entry.js:111:10)
at Entry.write (/home/n0t/stream-adventure/secretz/node_modules/tar/lib/entry.js:68:8)
at Parse._process (/home/n0t/stream-adventure/secretz/node_modules/tar/lib/parse.js:104:11)
at BlockStream.<anonymous> (/home/n0t/stream-adventure/secretz/node_modules/tar/lib/parse.js:46:8)
at BlockStream.EventEmitter.emit (events.js:95:17)
at BlockStream._emitChunk (/home/n0t/stream-adventure/secretz/node_modules/tar/node_modules/block-stream/block-stream.js:145:10)
and with the verify:
$> stream-adventure verify app
ACTUAL: "97911dcc607865d621029f6f927c7851"
EXPECTED: "97911dcc607865d621029f6f927c7851 secretz/METADATA.TXT"
ACTUAL: null
EXPECTED: "2cdcfa9f8bbefb82fb7a894964b5c199 secretz/SPYING.TXT"
ACTUAL: null
EXPECTED: ""
# FAIL
You get this error because entry writes into the md5 stream after is has been closed. Once a stream is closed, you can't write into it again: for md5 this is easy to understand because you have to reset the internal buffers, otherwise the hash will be skewed.
In your example, on each file in the tar module, you pipe the file stream into the same md5 stream. You just have to pipe the file stream into a new MD5 stream; here is how you can do it properly:
parser.on('entry', function(entry) {
if (entry.type === 'File') {
var md5 = crypto.createHash('md5', { encoding: 'hex' });
entry.pipe(md5).pipe(process.stdout);
console.log(entry.path);
}
});

Resources