Mocha Uncaught Error for catch exceptions - javascript

I am trying to write test cases for the below code:
async readFile(filename) {
try {
const fileStream = fs.createReadStream(filename);
const rs = readline.createInterface({
input: fileStream,
});
} catch (error) {
throw error.message;
}
}
test case:
await expect(readFile('invalid-file.txt')).to.be.rejectedWith(
"ENOENT, no such file or directory 'invalid-file.txt'",
);
I am getting error for the above test case:
Uncaught Error: ENOENT, no such file or directory 'invalid-file.txt'
at Binding.<anonymous> (node_modules/mock-fs/lib/binding.js:383:15)
How to write test case for catch exceptions?
Note: This test is passing in my local, but failing in Travis.
Thanks in advance.

Related

Sinon Stub is not throwing an error when fs.readFileSynch also throws an error

After going through all related issues regarding stubbing readFile/Sync with Sinon /Chai/ Mocha, the test is failing.
There's a basic getFile function that retrieves a file:
function getFile(path) {
const file = fs.readFileSync(path, "utf8)
return file;
}
module.exports = {getFile}
and I want to create a test where getFile should throw an error if fs.readFileSync also throws an error:
it('should throw an error if fs.readFileSync throws an error', () => {
I tried:
it('should throw an error if fs.readFileSync throws an error', () => {
const error = new Error('some error message')
const myStub = sinon.stub(fs, "readFileSync")
myStub.throws(error)
const filePath = "/Project/test.js"
const gFile = index.getFile(filePath)
try {
if(myStub.error === true) {
gFile(error)
} catch (error) {
expect(myStub).to.throw(error)
What I got was:
1 failing
Error: some error message
at Context.
at process.processImmediate
See the chai expect docs on throw(). There is this example:
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw();
You see that expect(badFn) gets badFn not badFn(), so nowhere in the test is badFn actually called.
This means that expect calls badFn. And actually, expect needs to be the one to call it because it needs to catch the error.
So in your code, try this:
const stub = sinon.stub(fs, 'readFileSync').throws();
const callGetFile = () => {
index.getFile('some_file');
};
expect(callGetFile).to.throw();
Try putting your error function in the Sinon throw method as below.
myStub.throws(new Error('some error message'));

Why does fs.writeFileSync() throws "is not a function" error?

I am trying to save some data in a file using fs.writeFileSync, but it doesn't work and I cannot figure out why. It throws the following error: Unhandled Rejection (TypeError): fs.writeFileSync is not a function
In my app I use it like this :
const fs = require('fs');
const stateFile = "./usersStateFile";
const saveLastEventSequenceId = (sequenceId) => {
try {
fs.writeFileSync(stateFile, sequenceId);
} catch (err) {
throw err;
}
};
The sequenceId is a number and the ./usersStateFile doesn't exist, but fs.writeFileSync() should create it if it doesn't exist.
What might be the problem ?
Import fs module like so:
const fs = require('fs'); // or `import * as fs from 'fs'` if you're using ES2015+
const stateFile = "./usersStateFile";
const saveLastEventSequenceId = (sequenceId) => {
try {
fs.writeFileSync(stateFile, sequenceId);
} catch (err) {
throw err;
}
};
You were calling fs.writeFileSync() without having a variable named fs that's defined in your scope. In this case, fs evaluates to undefined, which caused the error when trying to invoke its in-existent function member.

Firestore realtime listener error unhandled in node.js

I have made a function that I am exporting using node.js called return_match_uid. I am importing the function in another express routing file and am using async await, with try and catch to handle the error. But somehow, the errors produced by return_match_uid always slip and are unhandled, even though I am using the error handling for the realtime listener recommended by Firestore doc
Here is the function:
exports.return_match_uid = function return_match_uid() {
return new Promise((resolve, reject) => {
const unsub = db.collection('cities').onSnapshot(() => {
throw ("matching algo error");
resolve();
unsub();
}, err => {
console.log(err);
})
})
})
In another express router file, I am calling the function:
const Router = require('express').Router;
const router = new Router();
const {return_match_uid} = require("./match_algo");
router.get('/match', async (req, res) => {
try {
var match_user = await return_match_uid(req.query.data, req.query.rejected);
res.send(match_user);
}
catch (error) {
console.log("Matching algorithm return error: " + error);
}
})
The error I am throwing inside the function: matching algo error do not get caught by either the err => {console.log(err);}) in the function nor the try catch block in the router. It slips and causes my app to crash. It shows the following error:
throw "matching algo error!";
^
matching algo error!
(Use `node --trace-uncaught ...` to show where the exception was thrown)
[nodemon] app crashed - waiting for file changes before starting...
I am throwing an error inside matching algo error because I have some other codes in there, and there is a possibility that it produces an error. If it does, I would like to make sure that it gets handled properly.

Can't catch exception from fs.createWriteStream()

In the main process of my Electron app, I'm trying to handle an exception thrown when creating a file that already exists. However, my catch clause is never entered, and the exception is spammed to the user. What am I doing wrong?
let file;
try {
// this line throws *uncaught* exception if file exists - why???
file = fs.createWriteStream('/path/to/existing/file', {flags: 'wx'});
}
catch (err) {
// never gets here - why???
}
The correct way to handle this case is by listening to the error event:
const file = fs.createWriteStream('/path/to/existing/file', {flags: 'wx'});
file.on('error', function(err) {
console.log(err);
file.end();
});
What I've found is:
https://github.com/electron/electron/issues/2479
I tried to replicate with pure Node.js, and it catches errors with process.on('uncaughtException', callback)
let desiredPath = '/mnt/c/hello.txt';
let fs = require('fs');
process.on('uncaughtException', function (error) {
console.log('hello1');
});
try {
fs.createWriteStream(desiredPath, {
flags: 'wx',
});
}
catch (err) {
console.log('hello');
}
//Output is: 'hello1'
I tried it with Ubuntu shell on Windows 10, in my case I don't have permissions to read that file and process.on('uncaughtException', callback) catches it correctly.

Catching execSync errors

I'm using execSync to run a soffice command. The issue I'm having is when an error is thrown execSync just logs the error to the console there is no way of catching it. I've tried using a try catch statement but it still just logs the error to the console.
function convertToPdf(filepath, destpath) {
var cmd = 'sofice command';
try {
var res = execSync(cmd, { encoding: 'utf8' });
} catch (e) {
console.log("Errors:", e);
}
console.log("res:", res);
}
convertToPdf("test.docx");
I run this and get this back:
Error: source file could not be loaded
res:
Notice how my catch statement is never logged even though an error was clearly thrown but another Error: message is logged automatically because I'm not logging that.
try this:
function myExecSync(command, trim = true, cwd = pwd, opts = {}) {
const ret = execSync(command, { cwd, ...opts }).toString('utf-8');
return trim ? ret.trim() : ret;
}
And write stdio: 'pipe' manually to prevent childprocess.stderr output to the console. like
myExecSync(command, true, cwd, { stdio: 'pipe' })

Categories