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?
Related
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());
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);
});
I have an as promise as :
try {
myPromise().then(function(){
console.log("ok");
}, function(err) { throw err; });
} catch(e) {
console.log("error");
}
now my control goes to the function(err) and it throws the error but the error is not caught in catch().
Because promises are asynchronous, flow control doesn't work the way you're thinking it will. Your try...catch block is outside of the promise initialization code, and once it initializes the promise, it's done. So the try...catch block is only handling promise initialization in the code above. If the promise is rejected/errored (as you say it is doing in your code), the error function will fire within the error function closure only.
Consider a common error handler or you can refactor your try...catch block to be within the closure.
Here's the code with the common error handler:
try {
myPromise().then(function(){
console.log("ok");
}, function(err) {
errHandler(err);
});
} catch(e) {
errHandler(e);
}
function errHandler(err) {
console.log("error");
}
You have two options:
1) Use Promise.catch:
myPromise().then(function(){
console.log("ok");
}, function(err) { throw err; })
.catch(function(err) { console.log("error"); });
2) If you have transpiler use async/await:
async function parentFunction() {
try {
await myPromise();
console.log("ok");
}
catch (e) {
console.log("error");
}
}
I want to call a util function that might encounter an error. In case of an error the process function should be terminated. The only way to throw an error properly is the callback function.
I would terminate the function by returning, but since I am in the util function, the process function will continue after the util() call.
function util(callback) {
// do something synchronous
if (err) {
// doesn't terminate the process function
// since we are in the util function
return callback("something unexpected happened");
}
}
function process(callback) {
util(callback);
console.log("This should not be printed if an error occurs!");
}
process(function (err) {
if (err) {
// this has to be executed in case of an error
console.log(err);
// terminate the process function somehow?
}
});
Does calling the callback terminate the current function?
No, a callback is just a regular function. It might of course throw an exception (although that is despised).
I want to call a util function that might encounter an error. In case of an error the process function should be terminated.
For that, you need to check in the callback what did happen and act accordingly. You could use process.exit for termination.
function myProcess(callback) {
util(function(err, result) {
if (err) {
callback(err);
} else {
console.log("This should not be printed if an error occurs!");
callback(null, result);
}
});
}
myProcess(function (err) {
if (err) {
// this has to be executed in case of an error
console.log(err);
process.exit(1);
}
});
Notice that promises could simplify this a lot, as they distinguish between success and error callbacks. util would have to return a promise for that:
function util() {
return new Promise(function(resolve, reject) {
// do something asynchronous
if (err)
reject("something unexpected happened");
else
resolve(…);
});
}
function myProcess() {
return util().then(function(res) {
console.log("This should not be printed if an error occurs!");
return res;
});
}
myProcess().catch(function (err) {
// this has to be executed in case of an error
console.log(err);
process.exit(1); // you might not even need this:
throw err; // The node process will by default exit with an unhandled rejection
});
I suggest you make a few changes to your code
function util(callback) {
// do something synchronous
if (err) {
// doesn't terminate the process function
// since we are in the util function
callback("something unexpected happened");
return false;
}
return true;
}
function process(callback) {
if(!util(callback)) return;
console.log("This should not be printed if an error occurs!");
}
This seems like a good time to use a Promise, promises are Javascript's way of forcing a synchronous function. Basically you set it up like this:
var util = new Promise(function(resolve, reject) {
/* do some stuff here */
if (someCondition) {
resolve("With a message");
} else {
reject("with a message");
}
}
function process() {
util.then(function() {
console.log("Won't call if there is an error");
}).catch(function() {
console.log("There was an error, Bob");
});
}
No, you will want to do something like this:
function util(callback) {
// do something synchronous
if (err) {
throw new Error('Something unexpected happened');
}
callback(); // only execute callback if an error did not occur
}
function process(callback) {
try{
util(callback);
console.log("This should not be printed if an error occurs!");
} catch(error){
process(error);
}
}
process(function (err) {
if (err) {
// this has to be executed in case of an error
console.log(err);
process.exit(1)
}
});
My code is like this,
function promisefn1() {
return someFunction.then(function(data) {
//here i check some thing and throw an error
if (someConditions) {
throw new Error('some error');
}
return someOtherFunction();
});
}
function test() {
return bluebird.props({
attribute1: promisefn1(),
attribute2: promisefn2()
})
}
In the above code, if the error is thrown from promisefn1 the callee function test is not getting rejected. If I add an error handler in bluebird.props I get the error there. Can anyone tell what am I doing wrong here?