Unable to catch error from childprocess exec callback function - javascript

Context
I want to execute a comand line call in the backend of my website. If this comandline call fails, I want to catch the error and throw a new custom Error.
I tried to throw the error as follows:
async function someFunction(): Promise<void> {
...
const result = exec(`some command`);
result.on('error', (error) => {
console.log(error.message);
throw error;
});
}
and
async function someFunction(): Promise<void> {
...
exec(`some command`, (error) => {
if (error) {
throw error;
}
});
}
and catch it like this:
try {
await someFunction();
} catch (e) {
...
throw new Error('Meaningfull error')
}
Problem
But the code never reaches the catch block, as it shuts down the second i reacht the throw error.
Error: Command failed: some Command: Kommando nicht gefunden. //(Command not found)
at ChildProcess.exithandler (node:child_process:398:12)
at ChildProcess.emit (node:events:527:28)
at ChildProcess.emit (node:domain:475:12)
at maybeClose (node:internal/child_process:1092:16)
at Socket.<anonymous> (node:internal/child_process:451:11)
at Socket.emit (node:events:527:28)
at Socket.emit (node:domain:475:12)
at Pipe.<anonymous> (node:net:709:12) {
code: 127,
killed: false,
signal: null,
cmd: 'some Command'
}
Waiting for the debugger to disconnect...
[nodemon] app crashed - waiting for file changes before starting...
I tried removing the error handeling attempt and the app keeps on minding its own business. I don't understand why it keeps crashing when I trie to handle an error...
I am aware, that the command fails, and I don't care. I just want to be able to handle the error.
Edit 1
I also tried a try catch arround the exec call.
try {
exec(`some Command`, (error) => {
if (error) {
throw error;
}
});
} catch (e) {
throw e;
}
But sadly the app crashes right at the throw error line.
Edit 2
I use an restify middleware based error handler
this.restify.on('uncaughtException', function(req, res, route, err) {
res.send(500, err.message);
});
As an example. The Following code is beeing handled as expected:
if (!newUser.course) {
console.log('no course selected');
throw new Error('signal/no-course'); // error is thrown and handled accordingly
}
try {
await someFunction(newUser); // error in someFunction is thrown and crashes the app...
} catch (e) {
console.log(e);
throw new Error('signal/add-user');
}
I also tried adding console.log(error) in every catch. Didn't help.

Hello I think the correct way to approach this would be to wrap it into a Promise since it is an error within a callback, if you actually want to try and catch the error where it happens, it has to be done inside the callback as far as I am aware.
Possible solution:
function someFunction() {
return new Promise((resolve, reject) => {
exec(`some command`, (error) => {
if (error) {
reject(error);
}
resolve("coding is fun 😀");
});
})
}
async function main() {
try {
await someFunction();
} catch (e) {
console.error(e)
throw e;
}
}

Related

Unhandled exception while covered in try catch

The function createPool takes a callback, that will present an error if something went wrong with the connection. I want to throw an exception in case that happens Connection pool failed with error, but for some reason it keeps being unhandled and the try catch doesn't catch it. What can I change ?
try {
// Create a connection pool which will later be accessed via the
// pool cache as the 'default' pool.
await oracledb.createPool({
user: dbConfig.user,
password: dbConfig.password,
connectString: `${dbConfig.host}:${dbConfig.port}/${dbConfig.serviceId}`
}, (err) => {
if (err) {
throw `Connection pool failed with ${err.message}`;
} else {
console.log('Connection pool started');
}
}
)
} catch (err) {
console.log(err);
// propagate
throw err;
}
The exceptions is thrown inside the callback as expected:
(node:32) UnhandledPromiseRejectionWarning: Connection pool failed with ORA-24415: Missing or null username.
But I can't catch her in my outer try catch

Mongoose and multiple save error handling

I'm using mongoose + express to build a simple MERN app.
I need to create multiple documents and save them, but I need to catch all errors.
I'm using this code and it works, but I'd like to handle all errors at once, not repeat the same code multiple times.
If I use try...catch block and remove the callback error handler, I obtain UnhandledPromiseRejectionWarning.
model.save((err, doc) => {
if (err) return console.error(`ERR ${err.message}`);
});
I've tried this:
export const init = async () => {
try {
const newDoc = new MyModel({ test: 'test'});
const savedDoc = await newDoc.save();
console.log('All done :)');
} catch (err) {
console.log('Error');
res.status(400).send(err);
}
}
But I can't catch the error: in debug mode, the program never enter the catch block and I obtain, in case of error for example:
UnhandledPromiseRejectionWarning: MongoError: E11000 duplicate key error collection
Any suggestion?
model.save()
.then(success => {
if(!success) {
// Handle your error
}
// Success
return model2.save();
})
.then(success2 => {
})
// etc..
.catch(err => {
// Handle your error
});
try{
const savedModel = await model.save();
console.log("Model created successfully");
res.status(200).send("Model created successfully");
}catch (err){
console.log(err);
res.status(400).send(err);
}

will `return` be caught on error in a try/catch block?

I have a try/catch block within which I run my synchronous function call, I wonder why it won't be caught by the catch if the function return an Error. In this case I have a known issue in mySyncFunction and I don't want to throw on that, because I want the test function to catch that
function test() {
try {
return mySyncFunction();
} catch (error) {
console.error('my error message', error);
return [];
}
}
function mySyncFunction() {
try {
// Do stuff
const expectedIssue = true;
if (expectedIssue) {
return Error('the known issue happended');
}
} catch (e) {
throw Error(e)
}
}
console.log(test());
If there is no error occuring during the call of this.mySyncFunction(args) it will returns normally. However, if there is an exception raised during this call, it will simply go directly to the catch, console.error your error and return [].
You're not throwing an Error, you're returning one. Errors and other exception are only caught when you throw them, not by simply being around.
The correct way to actually see the exception being caught is
function test() {
try {
return mySyncFunction();
} catch (error) {
console.error('my error message', error.message); // notice error.message
return [];
}
}
function mySyncFunction() {
throw new Error('my error'); // notice throw
}
console.log(test());

Catch error outside callback of puppeteers listener page.on

I am occurring the following problem while implementing an end-to-end test with puppeteer.
I try to catch the thrown error outside the page listener. Unfortunately it is not accessable outside the callback of the page.on (puppeteer) listener.
(async () => {
try {
// http error handling
page.on('response', response => {
if (!response.ok() && response.request().resourceType() === 'xhr')
throw new Error('HTTP Error occurred');
});
} catch (err) {
// want to catch error here
console.log('error while running end-2-end test');
process.exit(1);
}
})();
I only log UnhandledPromiseRejectionWarning
This is a common problem with asynchronous code. Although your code looks like the exception is thrown inside the try-catch block, the function you are giving to the page.on function is run later and therefore any error thrown inside is not caught.
Therefore, you have to move the try-catch block into the function (in case the throw new Error is just example code). You can still call a function in the outer scope from inside the catch block if you want to. Alternatively, you could just remove the throw statement and call the handleError function directly.
function handleError(err) {
// handle the error
}
page.on('response', response => {
try {
if (!response.ok() && response.request().resourceType() === 'xhr') {
throw new Error('HTTP Error occurred');
}
} catch (err) {
handleError(err);
}
});
Using EventEmitter
You can create an instance on eventEmitter that will listen to some error or custom event.
// create your own error catching event
const events = require('events');
const catchErrors = new events.EventEmitter();
catchErrors.on('error', (err) => console.error(err));
Later on,
page.on('response', response => {
if (!response.ok() && response.request().resourceType() === 'xhr')
catchErrors.emit('error', new Error('HTTP Error occurred'));
});
Catch all errors
process.on('unhandledRejection', error => {
console.log('unhandledRejection', error.message);
});

Catch error thrown inside $.getJSON().done()

I'm accessing and doing some stuff with a JSON file. If the ajax call fails the error can be caught by .fail(), but when I throw an error inside .done() it doesn't get caught.
function myFunc() {
$.getJSON('data.json')
.done(db => {
/* do stuff with JSON */
if (condition) {
throw Error(message);
}
})
.fail(error => {
throw Error("getJSON request failed.\n" + error);
})
}
try {
myFunc();
} catch (e) {
/* handle error */
}
I understand this is because the function is asynchronous. How can I make sure this error is caught, and that myFunch() finishes executing before ending the try-catch block?

Categories