Why JSZip can't create blob file? - node.js

I was trying JSZip on NodeJS to create some ZIP file but i'm facing an issue.
I'm using the code proposed by JSZip :
var JSZip = require('JSZip')
var zip = new JSZip()
zip.file("Hello.txt", "Hello World\n")
zip.generateAsync({type:"blob"}).then(function(content) {
//do things here
});
Currently the code throw an error on generateAsync
UnhandledPromiseRejectionWarning: Error: blob is not supported by this platform
Did something need to be install or the data I set in zip.file should be in a certain format ?

JSZip throws this error at jszip/lib/utils.js:352:15 because of the value of support.blob, defined by at jszip/lib/support.js (lines 11 to 32). I don't know for your machine, but while trying to run this script in NodeJS, I've debugged it to the conclusion that JSZip detects blobs to be not supported because self is not defined, so line 23 throws an error and support.blob is set to false.
JSZip seems to support the Node Buffer type on Node though - the following doesn't throw any errors on my machine:
// JSZip v3.2.1
// NodeJS v8.10.0
// Ubuntu 18.04
const JSZip = require('jszip');
const zip = new JSZip();
zip.file('hello.txt', 'Hello world\n');
zip
.generateAsync({type: 'nodebuffer'}) // blob -> nodebuffer
.then(console.log);

Related

Cloud foundry Error : Array.includes is not a function

I am trying to traverse through an array returned by fs library in my node.js application. In my local machine the following code is working fine:
var fs = require('fs');
var data = fs.readdirSync("<directory>");
if(data.includes('a')){
console.log('value found!');
}
But when I uploaded my same application in CloudFoundry, i got the error as:
Error: data.includes is not a function
can anyone explain what could be the reason for the same.
"Includes" doesn't work with Node 5.x So,please check node version.In order to make it work in current version.just follow below code.or you upgrade node to version 6.
if(data.indexOf('a')> -1){
console.log('value found!');
}

Script fails when using python-shell Node.js package

So I'm having a pretty odd issue. I have a python script whose function is to analyze an image and produce an output string. I decided to implement this script into the backend of my NodeJS server using the package 'python-shell.' The funny thing is, this script works perfectly when it's run on its own. It is able to analyze the image and produce the output string. However, when I attempt to have the 'python-shell' package run it, there is an error that is produced (related to the python code). I've tested and the python-shell runs the same version of python as is used at the terminal, so I'm not 100% sure why this issue is occurring. For reference, the below code is how I'm running the script:
var express = require('express');
var router = express.Router();
var pythonshell = require('python-shell');
pythonshell.defaultOptions = { scriptPath: '/path/to/myscript.py' };
var outputString = '';
var options = {args: ['-p', '/path/to/image.jpg']}
var pyshell = new pythonshell('myscript.py', options);
pyshell.on('message', function(message) {
// received a message sent from the Python script
console.log(message);
outputString = message;
});
pyshell.end(function(err) {
// This is where the error occurs
if (err) throw err;
console.log('Picture analysis complete');
console.log('outputString: ' + outputString);
});
Again, when the script is manually run (i.e. python myscript.py -p image.jpg), it runs perfectly fine. I can include the code in myscript.py, although I doubt that will help as it doesn't seem to be an error with the actual python code. The image is analyzed using several packages including OpenCV (and the produced error is, I believe, based off that). Any tips are greatly appreciated!
change the default path
pythonshell.defaultOptions = { scriptPath: '/path/to/myscript.py' };

Electron app createWriteStream throwing ENOENT error

I'm trying to download files to the filesystem in an electron app. My code, in the main thread, looks like this:
const dir = `${__dirname}/media`;
if (!fs.existsSync(dir)){
fs.mkdirSync(dir);
}
const file = fs.createWriteStream(`${dir}/${name}`);
file.on("open", function() {
const request = http.get(url, function(response) {
response.pipe(file);
response.on('end', function() {
file.close();
...
});
});
request.on('error', function(err) {
...
});
});
This works when running in development using electron . But after I build it with electron-builder, I get the error in an alert:
Uncaught Exception:
Error: ENOENT, media/uploads_2016_02_BASF_Holistic_Program.jpg not found in /Users/nicholasstephan/Desktop/XXXXXXX/dist/Mac/XXXXXX.app/Contents/Resources/app.asar
at notFoundError (ELECTRON_ASAR.js:109:19)
at Object.module.(anonymous function) [as open] (ELECTRON_ASAR.js:209:16)
at WriteStream.open (fs.js:1890:6)
at new WriteStream (fs.js:1876:10)
at Object.fs.createWriteStream (fs.js:1831:10)
at next (/Users/nicholasstephan/Desktop/XXXXXXXX/dist/Mac/XXXXXXXX.app/Contents/Resources/app.asar/media.js:19:18)
at /Users/nicholasstephan/Desktop/XXXXXXXX/dist/Mac/XXXXXXXX.app/Contents/Resources/app.asar/media.js:52:4
...
where the media.js, ln 19, being referred to is the const file = fs.createWriteStream(${dir}/${name}); line in the code.
I've tried the solutions offered in about a dozen other similar stackoverflow answers, but none have fixed the problem.
What's going on here?
Thanks.
The built Electron app uses the Asar format. Asar is an archive format (it's really just one big file) though in Electron you are able to read from it as if it were a standard directory.
I presume (though I have not seen it explicitly documented) that it is not possible to write to an Asar with the fs functions. In any case there are almost certainly more appropriate locations to write data.
Try writing to a different path. Electron provides a number of useful paths using app.getPath(name) so you could for example write to the userData directory which holds configuration files for your app.

reading a packaged file in aws lambda package

I have a very simple node lambda function which reads the contents of packaged file in it. I upload the code as zip file. The directory structure is as follows.
index.js
readme.txt
Then have in my index.js file:
fs.readFile('/var/task/readme.txt', function (err, data) {
if (err) throw err;
});
I keep getting the following error NOENT: no such file or directory, open '/var/task/readme.txt'.
I tried ./readme.txt also.
What am I missing ?
Try this, it works for me:
'use strict'
let fs = require("fs");
let path = require("path");
exports.handler = (event, context, callback) => {
// To debug your problem
console.log(path.resolve("./readme.txt"));
// Solution is to use absolute path using `__dirname`
fs.readFile(__dirname +'/readme.txt', function (err, data) {
if (err) throw err;
});
};
to debug why your code is not working, add below link in your handler
console.log(path.resolve("./readme.txt"));
On AWS Lambda node process might be running from some other folder and it looks for readme.txt file from that folder as you have provided relative path, solution is to use absolute path.
What worked for me was the comment by Vadorrequest to use process.env.LAMBDA_TASK_ROOT. I wrote a function to get a template file in a /templates directory when I'm running it locally on my machine with __dirname or with the process.env.LAMBDA_TASK_ROOT variable when running on Lambda:
function loadTemplateFile(templateName) {
const fileName = `./templates/${templateName}`
let resolved
if (process.env.LAMBDA_TASK_ROOT) {
resolved = path.resolve(process.env.LAMBDA_TASK_ROOT, fileName)
} else {
resolved = path.resolve(__dirname, fileName)
}
console.log(`Loading template at: ${resolved}`)
try {
const data = fs.readFileSync(resolved, 'utf8')
return data
} catch (error) {
const message = `Could not load template at: ${resolved}, error: ${JSON.stringify(error, null, 2)}`
console.error(message)
throw new Error(message)
}
}
This is an oldish question but comes up first when attempting to sort out whats going on with file paths on Lambda.
Additional Steps for Serverless Framework
For anyone using Serverless framework to deploy (which probably uses webpack to build) you will also need to add the following to your webpack config file (just after target: node):
// assume target: 'node', is here
node: {
__dirname: false,
},
Without this piece using __dirname with Serverless will STILL not get you the desired absolute directory path.
I went through this using serverless framework and it really was the file that was not sent in the compression. Just add the following line in serverless.yml:
package:
individually: false
include:
- src/**
const filepath = path.resolve('../../filename.text');
const fileData2 = fs.readFileSync(process.env.LAMBDA_TASK_ROOT + filepath, 'utf-8');
I was using fs.promises.readFile(). Couldn't get it to error out at out. The file was there, and LAMBDA_TASK_ROOT seemed right to me as well. After I changed to fs.readFileSync(), it worked.
I hade the same problem and I tried applying all these wonderful solutions above - which didn't work.
The problem was that I setup one of the folder name with one letter in upper case which was really lowercase.
So when I tried to fetch the content of /src/SOmething/some_file.txt
While the folder was really /src/Something/ - I got this error...
Windows (local environment) is case insensitive while AWS is not!!!....

Unable to read a saved file in heroku

I am using NodeJS on heroku.
I read a file from another server and save it into my application in the /temp directory.
Next, I read the same file to pass it on to my client.
The code that saves the file and then subsequently reads it is:
http.request(options, function (pdfResponse) {
var filename = Math.random().toString(36).slice(2) + '.pdf',
filepath = nodePath.join(process.cwd(),'temp/' + filename);
pdfResponse.on('end', function () {
fs.readFile(filepath, function (err, contents) {
//Stuff to do after reading
});
});
//Read the response and save it directly into a file
pdfResponse.pipe(fs.createWriteStream(filepath));
});
This works well on my localhost.
However, when deployed to heroku, I get the following error:
events.js:72
throw er; // Unhandled 'error' event
Error: ENOENT, open '/app/temp/nvks0626yjf0qkt9.pdf'
Process exited with status 8
State changed from up to crashed
I am using process.cwd() to ensure that the path is correctly used. But even then it did not help. As per the heroku documentation, I am free to create files in the applications directory, which I am doing. But I can't figure out why this is failing to read the file...
The error you describe there is consistent with /app/temp/ not existing. You need to create it before you start writing in it. The idea is:
var fs = require("fs");
var path = require("path");
var temp_dir = path.join(process.cwd(), 'temp/');
if (!fs.existsSync(temp_dir))
fs.mkdirSync(temp_dir);
I've used the sync version of the calls for illustrations purposes only. This code should be part of the start up code for your app (instead of being called for each request) and how you should structure it depends on your specific application.

Resources