can't get an expect console output when using async await - javascript

function fails4() {
return new Promise((resolve, reject) => {
setTimeout(function () {
reject(new Error());
}, 100);
});
}
async function myFunc4() {
try {
await fails4();
} catch (e) {
console.log(e);
console.log('that failed', e); //<-- this gets called
}
}
async function loadmYScript() {
try {
await myFunc4();
} catch (error) {
console.log(error);
console.log(123);
}
}
loadmYScript();
cant't execute the console.log(123) as I expected can anybody help me with this question very appreciated

You're calling loadmYScript, which in turn calls myFunc4, which in turn calls fails4. This last one (fails4) throws an error. The error is "catch-ed" by myFunc4. Inside this catch block you don't throw any error, there's only a couple of logs, so the result of loadmYScript is a fulfilled promise with undefined value. It is not rejected because myFunc4 doesn't throw the error.
If you throw an error inside the catch block of myFunc4, you will have your 123 logged, and the promise will be rejected.

Related

Catch block wrapping a function that throws inside a setTimeout not executed

Experienced something strange recently, none of the catch blocks get executed:
function funcWillThrow() {
try {
setTimeout(() => {
throw "Has thrown";
}, 3000);
} catch (error) {
console.log(error)
}
}
function caller() {
funcWillThrow();
}
caller();
and
function funcWillThrow() {
setTimeout(() => {
throw "Has thrown";
}, 3000);
}
function caller() {
funcWillThrow();
}
try {
caller();
} catch (error) {
console.log(error);
}
And according to the mdn docs
Execution of the current function 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.
My guess is that something is happening with the callstack as stated in the docs. Any ideas as to what might be happening.
setTimeout calls the supplied function at a later time (3 seconds later in your specific code), and by then the function which called setTimeout has long since terminated.
To catch the exception in your later function, put the error handling in that function:
function funcWillThrow() {
setTimeout(() => {
try {
throw "Has thrown";
} catch (error) {
console.log(error);
}
}, 3000);
}
Based on your comment below, you may be looking for Promises. Since the operation is asynchronous and happens outside of the stack which invoked it, in order to catch the error in that stack you'd need to await the operation. Ideally you'd make use of the reject functionality of the Promise. Something like this:
function funcWillThrow() {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject("Has thrown");
}, 3000);
});
}
(async () => {
try {
await funcWillThrow();
} catch (err) {
console.log(err);
}
})();
If you specifically need to be able to throw from within the setTimeout callback, you'd either need to catch there as well:
function funcWillThrow() {
return new Promise((resolve, reject) => {
setTimeout(() => {
try {
throw "Has thrown";
} catch (error) {
reject(error);
}
}, 3000);
});
}
(async () => {
try {
await funcWillThrow();
} catch (err) {
console.log(err);
}
})();
Or customize setTimeout itself as a Promise and use normal error handling with that:
function myTimeout(ms) {
return new Promise(function(resolve) {
setTimeout(resolve, ms);
});
}
(async () => {
try {
await myTimeout(3000).then(() => {
throw "Has thrown";
});
} catch (err) {
console.log(err);
}
})();

"await is only valid in async function" in for loop

I'm being told that "await is only valid in async function", even though it is in a async function. Here is my code:
async function uploadMultipleFiles (storageFilePaths,packFilePaths,packRoot) {
return new Promise((resolve,reject) => {
try {
for (i in storageFilePaths) {
await uploadFile(storageFilePaths[i],packFilePaths[i],packRoot) // error throws on this line
}
resolve("files uploaded")
} catch {
console.log(err)
reject("fail")
}
})
}
Why is this happening when I made it an async function? Is it because I am using a for loop? If so, how can I get the expected outcome without this error?
The function you define starting on line 1 is async.
The arrow function you define on line 2 and pass to the Promise constructor is not async.
You are also using the multiple promise anti-pattern. Get rid of the Promise constructor entirely. Just return the value when you have it. That's one of the main benefits of the async keyword.
async function uploadMultipleFiles(storageFilePaths, packFilePaths, packRoot) {
try {
for (i in storageFilePaths) {
await uploadFile(storageFilePaths[i], packFilePaths[i], packRoot) // error throws on this line
}
return "files uploaded";
} catch {
console.log(err);
throw "fail";
}
}
You can only use await inside of an async function, the error refers to the callback your passing to your new Promise (since you are entering a new function scope there).
async function uploadMultipleFiles (storageFilePaths,packFilePaths,packRoot) {
return new Promise((resolve,reject) => { // <========= this arrow function is not async
try { // so you cant use await inside
for (i in storageFilePaths) {
await uploadFile(storageFilePaths[i],packFilePaths[i],packRoot) // error throws on this line
}
resolve("files uploaded")
} catch {
console.log(err)
reject("fail")
}
})
}
The part where you try to construct a new Promise is actually redundant since an async function will resolve to a Promise anyways (read more here). So you could write your code as follows:
async function uploadMultipleFiles (storageFilePaths,packFilePaths,packRoot) {
try {
for (i in storageFilePaths) {
await uploadFile(storageFilePaths[i],packFilePaths[i],packRoot) // error throws on this line
}
return "files uploaded"
} catch {
console.log(err)
throw new Error("fail");
}
}
The Promise callback isn't async
async function uploadMultipleFiles (storageFilePaths,packFilePaths,packRoot) {
return new Promise(async (resolve,reject) => {
try {
for (i in storageFilePaths) {
await uploadFile(storageFilePaths[i],packFilePaths[i],packRoot) // error throws on this line
}
resolve("files uploaded")
} catch {
console.log(err)
reject("fail")
}
})
}

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();

How to catch a callback error with a try catch?

I have an async function that grabs the contents of a file, like so:
async function getFile (name) {
return new Promise(function (resolve, reject) {
fs.readFile(`./dir/${name}.txt`, 'utf8', function (error, file) {
if (error) reject(error)
else resolve(file)
})
})
}
And I call that function into a console log
getFile('name').then( console.log )
If I make an error, like misspelling the file name, I get this handy error:
(node:17246) 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)
I can fix it by doing this:
getFile('name').then( console.log ).catch( console.log ) but is there a way to deal with the error within the callback? Perhaps a try catch? How would I do that?
You still need to catch errors that are rejected.
I think it's where you call your getFile function from - that needs to be wrapped in a try/catch block
try {
const result = await getFile('name')
} catch(e) {
... You should see rejected errors here
}
Or, I think this would work for your example:
await getFile('name').then( console.log ).catch(e => {...})
Testing this in the Chrome DevTools console:
async function test () {
return new Promise(function(resolve, reject) {
throw 'this is an error';
})
}
And calling it via the following:
await test().catch(e => alert(e))
Shows that this does, in fact, work!
If I understand correctly, you want your function to resolve regardless of whether you got and error or not. If so you can just resolve in either case:
async function getFile (name) {
return new Promise(function (resolve, reject) {
fs.readFile(`./dir/${name}.txt`, 'utf8', function (error, file) {
if (error) resolve(error)
else resolve(file)
})
})
}
Then you'd need to handle the errors outside, e.g.
getFile('name')
.then(getFileOutput => {
if (getFileOutput instanceof Error) {
// we got an error
} else {
// we got a file
}
})
or
const getFileOutput = await getFile('name');
if (getFileOutput instanceof Error) {
// we got an error
} else {
// we got a file
}
Is that what you're looking for?

Promises: some problems with reject

I have an issue with promise in 'Angular 2'.
Please see my code below:
getPromise1().then((result) => {
console.log("promise1 result");
}, (error) => {
console.log("promise1 error");
});
function getPromise1() {
return getPromise2().then((result) => {
console.log("promise2 result");
}, (error) => {
console.log("promise2 error");
});
}
function getPromise2() {
return new Promise((resolve, reject) => {
reject("error");
});
}
And the result is: promise2 error and promise1 result.
I don't know why not promise2 error and promise1 error
Any problem and the solution for this case?
This is preview link: http://plnkr.co/edit/RTc1wYfO8e1YPUrXM6GN
When a promise rejects, the control jumps to the closest rejection handler down the chain.
so, Here the .catch block finishes normally. So the next successful handler is called. Or it could return something, that would be the same.
Hence the result
And the result is: promise2 error and promise1 result.
So you could have as many .then as we want, and then use a single .catch at the end to handle errors in all of them.
But to get the following result
I don't know why not promise2 error and promise1 error
you need to re-throw the error
throw error;
And here the .catch block analyzes the error and throws it again:
function getPromise1() {
return getPromise2().then((result) => {
console.log("promise2 result");
}, (error) => {
console.log("promise2 error");
throw error;
});
}
If you handle a rejection in any promise chain then that's going to make the resulting chain to be fulfilled until an error is found then it goes back to being rejected. Think about it in terms of sync code, would you have expected this to print error A and error B?
function myFnA(){
throw new Error('A is bad');
}
function myFnB(){
try {
myFnA();
console.log('good A');
} catch(e){
console.log('error A');
}
}
function myFnC(){
try {
myFnB();
console.log('good B');
}
catch(e){
console.log('error B');
}
}
myFnC();
myFnB fixes myFnA error. So myFnB is doing it's job right.

Categories

Resources