Inner promise returning a catch - javascript

Will the promise rejection that is returned inside catch gonna get received outside of the outer promise?
promisedFunction().then((result) => {
return anotherPromisedFunction().then((result) => {
....
}).catch((error) => {
return Promise.reject(error);
});
}).catch((error) => {
//catch inner error here
});;

The then method returns a Promise, in your case, you are returning a rejected promise, so yes, the outer catch should handle that.

Related

How can I "throw" inside "catch" method from a rejected promise to be handled by an outer "catch" bock?

This is working !
function rejectedPromise() {
return Promise.reject("ERROR");
}
async function someFunction() {
try {
rejectedPromise()
.catch((err) => console.log(err)); // IT WORKS ! THE ERROR IS BEING LOGGED HERE
}
catch(err) {
console.log(err);
}
}
someFunction();
This is not.
function rejectedPromise() {
return Promise.reject("ERROR");
}
async function someFunction() {
try {
rejectedPromise()
.catch((err) => { throw err; }); // CAN'T I THROW HERE ?
}
catch(err) {
console.log(err); // DOES NOT WORK. THE ERROR SHOULD BE LOGGED HERE
}
}
someFunction();
QUESTION
Why?
Note: my goal is to throw the error from the catch method of the rejected Promise and throw it so it's handled by an outer catch block. Don't know if it matters, but this is happening inside an async function (it doesn't work if I remove the async keyword from the example anyways).
EXTRA:
In Node, I'm getting this (even though there's a catch block):
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with
.catch(). (rejection id: 1)
As pointed out in the comments, there is no need for using .catch() if you are inside an async function. I don't know why you want nested try...catch, but it looks like this would achieve what you want:
function rejectedPromise() {
return Promise.reject("ERROR");
}
async function someFunction() {
try {
try {
await rejectedPromise()
}
catch(err) {
throw err;
}
}
catch(err) {
console.log(err);
}
}
someFunction();

Nested promise not throwing error in parent catch block

My code :
return resultSet.reduce (prev,next)=> {
return function1 ({
}).then(response => {
console.log('suscess' + someID)
return functionA (response.someID)
}).catch (err => {
console.log('failed' + someID)
return functionB (response.someID)
})
}, promise.resolve());
function1: function (){
return function2_Credentials().then{
return function3_insertSqlRecord().then{
return function4_appSearch().then (function(response){
return function5().then (return response)
.catch (function (error){
throw Error(error);
});
});
}.catch (function(error){
throw Error(error);
});
}
}.catch (function(error){
throw Error(error);
});
Inside my nested promise, if any of the inner functions failed I can get the error in catch block but it is not available function1 catch block. For example If i get function4_appSearch fails and return any error that error is accessible to the last catch block but not carried away until the function1's catch block. why am I not getting the error at console.log('failed' + someID) ? and how do I get access of error from child promise untill to the parent pormise's catch block?
Your current code isn't valid; it has multiple syntax errors, and everything ever passed to a .then needs to be a Promise. Instead of
return function3_insertSqlRecord().then{
return function4_appSearch().then
you should do something like
return function3_insertSqlRecord()
.then(function4_appSearch)
.then( // etc
This keeps your code flat and ensures that that the Promises each function generates are chained properly.
If you want the caller of function1 to handle the error, then just let the error propagate up the Promise chain - don't .catch inside function1, because whenever you .catch, a resolved Promise results (but you want the caller to be able to see a rejected Promise). You can explicitly throw inside the .catch to make the Promise reject, but if that's all you're doing inside the .catch, there isn't really any point.
Try this instead:
function function1() {
return function2_Credentials()
.then(function3_insertSqlRecord)
.then(function4_appSearch)
.then(function5);
}
There also isn't any point to using reduce if you aren't going to use the accumulator (here, prev) or the item in the array you're iterating over (next).

How to fix stop promise returned in .catch beeing processed in the .then block of the preceding promise. Ie .catch should stay in .catch

Then a promise calls another promise and the inner promise returns from catch the outer one processes in the .then block
I have searched here and google generally.
Tried to use a simple try.. catch. But will not work with calling a promise
assignResolver(data)
.then(function(resp) {
console.log("map then");
console.log(resp);
})
.catch(function(err) {
console.log("map catch");
console.log(err);
});
export async function assignResolver(data) {
csrf();
return api
.post("/api/task/assignResolver", data)
.then(function(res){
console.log("in api then block");
return res.data;
} )
.catch(function(err) {
console.log("in api then block");
console.log(err);
});
}
Just throw the error again, when inside the inner catch, and it'll be handled in the outer catch, and not the outer .then:
export async function assignResolver(data) {
csrf();
return api
.post("/api/task/assignResolver", data)
.then(function(res){
console.log("in api then block");
return res.data;
} )
.catch(function(err) {
console.log("in api then block");
console.log(err);
throw err;
});
}
But this is a bit strange to do - it usually makes more sense to catch in only one place. For example, if assignResolver really needs to be able to do something specific when encountering an error, and your outer caller needs to be able to do something else when encountering the error as well, having two catches can be an option, but in most cases, you can just have a single catch wherever the error can be handled properly.
Here, unless assignResolver itself needs to do something on encountering the error, leave out its catch entirely:
export async function assignResolver(data) {
csrf();
return api
.post("/api/task/assignResolver", data)
.then(function(res){
console.log("in api then block");
return res.data;
})
}
.catch is meant to handle the error, so afterwards the promise chain will continue regularily with the next .then. To continue with the next .catch you have to rethrow the error from inside the .catch or return a rejected promise.

Value of Promise.all() after it is rejected, shows [''PromiseStatus'']: resolved if catch block is present

I have two promises, one rejected and other resolved. Promise.all is called. It executed the catch block of Promise.all as one of the promises is rejected.
const promise1 = Promise.resolve('Promise 1 Resolved');
const promise2 = Promise.reject('Promise 2 Rejected');
const promise3 = Promise.all([promise1, promise2])
.then(data => {
console.log('Promise.all Resolved', data);
})
.catch(error => {
console.log('Promise.all REJECTED', error);
})
setTimeout(() => {
console.log(promise1, promise2, promise3)
}, 200);
If I don't have the catch on Promise.all(), the value remains as Rejected, ie
const promise3 = Promise.all([promise1, promise2])
.then(data => {
console.log('Promise.all Resolved', data);
})
Am I missing something about promises.
I see that its answer but I think I can clarify a bit more.
Please remember that each then() or catch() return a Promise. (If you don't have any explicit return in callback, both will return Promise.resolve(undefined)). Therefore after the promise has resolved, the value of entire promise chain will be the promise returned by last then();
Example:
promise = Promise.resolve(1)
.then(() => Promise.resolve(2))
.then(() => Promise.resolve(3));
console.log(promise);
setTimeout(() => {
console.log(promise)//PromiseĀ {<resolved>: 3}
}, 0)
catch() works in exactly like then(). The only difference is that its called on rejected promises rather then resolved.
In following example, I just replace all resolve by reject to demonstrate that.
promise = Promise.reject(1)
.catch(() => Promise.reject(2))
.catch(() => Promise.reject(3));
console.log(promise);
setTimeout(() => {
console.log(promise)//Promise {<rejectd>: 3}
}, 0)
Now coming to your question. Value of Promise.all() is a rejected promise, since one of the promise in array is rejected. If you have a catch block in chain, control will go to that catch block which will return a Promise.resolve(undefined). If you have no catch block in the chain, you will get what you have: a rejected promise.
A catch on a Promise acts the same as a try {} catch {} block, in that you have captured the error state and the program will continue to function as normal.
That's why, when you omit the catch, your promise state is "rejected".
If, after having caught the error, you want to return the promise state as rejected you need to return a rejected promise from the catch handler:
const promise3 = Promise.all([promise1, promise2])
.catch(error => {
console.log("REJECTED", error);
return Promise.reject(error);
});
console.log(promise3); // [[PromiseStatus]]: "rejected"
Similar to doing a throw inside a try {} catch { throw; } block

Rethrowing error in promise catch

I found the following code in a tutorial:
promise.then(function(result){
//some code
}).catch(function(error) {
throw(error);
});
I'm a bit confused: does the catch call accomplish anything? It seems to me that it doesn't have any effect, since it simply throws the same error that was caught. I base this on how a regular try/catch works.
There is no point to a naked catch and throw as you show. It does not do anything useful except add code and slow execution. So, if you're going to .catch() and rethrow, there should be something you want to do in the .catch(), otherwise you should just remove the .catch() entirely.
The usual point for that general structure is when you want to execute something in the .catch() such as log the error or clean up some state (like close files), but you want the promise chain to continue as rejected.
promise.then(function(result){
//some code
}).catch(function(error) {
// log and rethrow
console.log(error);
throw error;
});
In a tutorial, it may be there just to show people where they can catch errors or to teach the concept of handling the error, then rethrowing it.
Some of the useful reasons for catching and rethrowing are as follows:
You want to log the error, but keep the promise chain as rejected.
You want to turn the error into some other error (often for easier error processing at the end of the chain). In this case, you would rethrow a different error.
You want to do a bunch of processing before the promise chain continues (such as close/free resources) but you want the promise chain to stay rejected.
You want a spot to place a breakpoint for the debugger at this point in the promise chain if there's a failure.
You want to handle a specific error or set of errors, but rethrow others so that they propagate back to the caller.
But, a plain catch and rethrow of the same error with no other code in the catch handler doesn't do anything useful for normal running of the code.
Both .then() and .catch() methods return Promises, and if you throw an Exception in either handler, the returned promise is rejected and the Exception will be caught in the next reject handler.
In the following code, we throw an exception in the first .catch(), which is caught in the second .catch() :
new Promise((resolve, reject) => {
console.log('Initial');
resolve();
})
.then(() => {
throw new Error('Something failed');
console.log('Do this'); // Never reached
})
.catch(() => {
console.log('Something failed');
throw new Error('Something failed again');
})
.catch((error) => {
console.log('Final error : ', error.message);
});
The second .catch() returns a Promised that is fulfilled, the .then() handler can be called :
new Promise((resolve, reject) => {
console.log('Initial');
resolve();
})
.then(() => {
throw new Error('Something failed');
console.log('Do this'); // Never reached
})
.catch(() => {
console.log('Something failed');
throw new Error('Something failed again');
})
.catch((error) => {
console.log('Final error : ', error.message);
})
.then(() => {
console.log('Show this message whatever happened before');
});
Useful reference : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#Chaining_after_a_catch
Hope this helps!
There is no important difference if you leave out the catch method call completely.
The only thing it adds is an extra microtask, which in practice means you'll notice the rejection of the promise later than is the case for a promise that fails without the catch clause.
The next snippet demonstrates this:
var p;
// Case 1: with catch
p = Promise.reject('my error 1')
.catch(function(error) {
throw(error);
});
p.catch( error => console.log(error) );
// Case 2: without catch
p = Promise.reject('my error 2');
p.catch( error => console.log(error) );
Note how the second rejection is reported before the first. That is about the only difference.
So it sounds like your question is, "In the promise chain, what does the .catch() method do?"
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw
The throw statement "will stop (the statements after throw won't be executed), and control will be passed to the first catch block in the call stack. If no catch block exists among caller functions, the program will terminate."
In the promise chain, the .then() method will return some type of data chunk. This return of the chunk will complete the promise. The successful return of the data completes the promise. You can think of the .catch() method in the same way. .catch() however will handle unsuccessful data retrieves. The throw statement completes the promise. Occasionally, you will see developers use .catch((err) => {console.log(err))} which would also complete the promise chain.
You actually don't need to re throw it, just leave the Promise.catch empty otherwise it will consider as un handle the reject and then wrap the code in a try catch and it will catch the error automatically which is passing down.
try{
promise.then(function(result){
//some code
}).catch(function(error) {
//no need for re throwing or any coding. but leave this as this otherwise it will consider as un handled
});
}catch(e){
console.log(e);
//error can handle in here
}
In the promise chain, it is better to use .catch
ex in function f2: .then(...).catch(e => reject(e));
test1 - with try catch
test2 - without try or .catch
test3 - with .catch
function f1() {
return new Promise((resolve, reject) => {
throw new Error('test');
});
}
function f2() {
return new Promise((resolve, reject) => {
f1().then(value => {
console.log('f1 ok ???');
}).catch(e => reject(e));
});
}
function test1() {
console.log('test1 - with try catch - look in F12');
try {
f2().then(() => { // Uncaught (in promise) Error: test
console.log('???'); });
} catch (e) {
console.log('this error dont catched');
}
}
function test2() {
console.log('test2 - without try or .catch - look in F12');
f2(); // Uncaught (in promise) Error: test
}
function test3() {
console.log('test3 - with .catch');
f2().then(value => {
console.log('??');
}).catch(e => {
console.log(' now its ok, error ', e);
})
}
setTimeout(() => { test1();
setTimeout(() => { test2();
setTimeout(() => { test3();
}, 100);
}, 100);
}, 100);

Categories

Resources