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?
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'm trying to do some validations before creating/updating an entry as shown below:
async save(){
return new Promise((resolve, reject)=>{
if(!this.isCampaignValid){
this.handleError()
reject()
}
else{
this.$store
.dispatch('updateCampaign')
.then((res)=>{
resolve()
this.showNotification(res.message, 'success')
})
.catch(error=>{
this.showNotification(error.message, 'error')
reject()
})
}
})
},
the isCampaignValid is a computed value which computes the validity.
If the campaign is not valid, then I'm getting an error in the console as below:
Uncaught (in promise) undefined
The this.handleError() function works too. How can handle this promise error situation?
Just in case handleError() throws, try:
if (!this.isCampaignValid) {
try {
this.handleError()
} catch (e) {
console.error(e);
}
reject()
}
First of all, you don't need to return a promise in an async function. It implicitly returns one, resolving with the value returned by the function or rejecting with the error object if the function throws. Although you could return a promise and JS unpacks it for you, it's unneeded code.
That said, because async returns a promise, you'll have to catch that promise too. Since your first conditional block just throws an error but doesn't catch it, the promise returned by save will reject. You need to handle that rejection.
Here's a simplified version of your code to see where it's happening.
async save(){
if(!this.isCampaignValid){
this.handleError()
// Throwing an error in an async function is equivalent to a reject.
throw new Error('Campaign is not valid') // Here
}
else{
try {
const res = await this.$store.dispatch('updateCampaign')
this.showNotification(res.message, 'success')
} catch (e) {
this.showNotification(error.message, 'error')
}
}
},
// When you call save, catch the error
yourObject.save()
.then(() => {...})
.catch(() => {...})
// If your call is in an async function, you can try-catch as well
try {
await yourObject.save()
} catch(e) {
// It failed.
}
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'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?
I have the following TypeScript method which returns a promise:
public loadSavedLogin(): ng.IPromise<MyApp.Models.User> {
return this._myAppService.getUser(this.savedUserId).then((result: MyApp.Models.User) => {
if (result) {
this.userId = result.UserID;
this.userName = result.UserName;
}
return result;
}, (error) => {
this._isAuthError = true;
return error;
}
);
}
The problem I have is in the promise's error callback. The upstream calls to this method also rely on a promise so if the error does not bubble up correctly, the upstream promise doesn't function correctly. I found a hackish solution:
(error) => {
try {
this._isAuthError = true;
return error;
} catch (e) {
//If any error occurred above make sure to still throw
throw error;
} finally {
//Allow upstream promises to continue as expected
throw error;
}
}
This works but looks, feels, and is probably all wrong. I feel like I'm missing a proper implementation when handling and bubbling errors in a promise. There has to be a more proper/correct way of handling the error function in this promise as I've done, and yet still allow upstream promise's making a call to this method to work properly as well when handling their own error function.
How do I get the error to bubble without the series of hackish throw statements?
Note: It seems redundant to return the error and throw as well, but the IPromise interface I'm using will not compile if I don't return a value. This is why I return and throw the error.
Note: I read a ton of the questions on handling errors with promises, but none of them are answering the question as I'm asking in regards to preventing the hackish approach I've taken.
I am not conversant with TypeScript, but here is a javascript solution, where you use $q.reject
.then(function() {},
function(error) {
this._isAuthError = true;
return $q.reject(error);
});`
Just throw the error instead of ever returning it:
public loadSavedLogin(): ng.IPromise<MyApp.Models.User> {
return this._myAppService.getUser(this.savedUserId).then((result: MyApp.Models.User) => {
if (result) {
this.userId = result.UserID;
this.userName = result.UserName;
}
return result;
}, (error) => {
this._isAuthError = true;
throw error;
}
);
}
Note that a valid return (i.e. not returning a promise / rejected promise) from a rejection handler makes the next promise in the chain fulfilled.