Can't throw error from within an async promise executor function
This is the async/await version of the Promise
constructor antipattern!
Never ever use an async function
as a Promise
executor function (even when you can make it work1)!
[1: by calling resolve
and reject
instead of using return
and throw
statements]
by "asynchronous" they're not referring to
async
functions, so I don't think their explanations apply here
They could as well. A simple example where it cannot work is
new Promise(async function() {
await delay(…);
throw new Error(…);
})
which is equivalent to
new Promise(function() {
return delay(…).then(function() {
throw new Error(…);
});
})
where it's clear now that the throw
is inside an asynchronous callback.
The Promise
constructor can only catch synchronous exceptions, and an async function
never throws - it always returns a promise (which might get rejected though). And that return value is ignored, as the promise is waiting for resolve
to be called.
Async promise executor functions
You don't need to create a new promise yourself because async
functions always return a promise. If the return value of an async
function is not a promise, it is implicitly wrapped in a promise.
So you need to remove the code that creates a new promise instance and the code inside the executor function should be at the top-level in the processFolder
function.
Your code can be simplified as shown below:
async function processFolder(folder) {
const table = {};
const list = await getHTMLlist(folder);
if (list.length > 0) {
for (let i = 0; i < list.length; i++) {
await processFile(folder, list[i], table);
}
}
return table;
}
Ideally, you should also wrap the code inside the processFolder
function in a try-catch
block to catch and handle any errors that might occur during the execution of this function.
Is it an anti-pattern to use async/await inside of a new Promise() constructor?
You're effectively using promises inside the promise constructor executor function, so this the Promise constructor anti-pattern.
Your code is a good example of the main risk: not propagating all errors safely. Read why there.
In addition, the use of async
/await
can make the same traps even more surprising. Compare:
let p = new Promise(resolve => { ""(); // TypeError resolve();});
(async () => { await p;})().catch(e => console.log("Caught: " + e)); // Catches it.
Correct error handling of nested async functions with promise
No you cannot catch same error twice. The method of relaying error will be buggy. instead what I would do is to just forward the outputs and handle them in the outer function.
const innerFunction = async () => asyncFunction(false); // <-- Just return the outputs
const outerFunction = async () => {
try {
const result = await innerFunction(); // <-- Error is forwarded and thus handled
} catch (error) {
console.log("Caught error inside outerFunction");
}
};
How to properly handle reject in Promises
Couple of problems in your code:
You are unnecessarily creating a promise;
auth.post(..)
already returns a promise, so you don't need to create a promise yourself and wrapauth.post(...)
inside a promise constructor.Another problem in your code is that executor function (function passed to the promise constructor) is marked as
async
; it should not be an async function.
Your function could be re-written as:
const userLogin = async (loginData) => {
const res = await auth.post("/login", loginData);
if (res.status !== 201) {
throw new Error("Error"));
}
return res;
};
You could also re-write your function as:
const userLogin = async (loginData) => {
return auth.post("/login", loginData);
};
Don't forget to use the catch
in the code that calls this function.
You might want to read the following article to understand whether you need the try-catch
block: await vs return vs return await
Promise constructor with reject call vs throwing error
Is there any difference between using
reject
(inp2
) from thePromise
api, and throwing an error (inp1
) usingthrow
?
Yes, you cannot use throw
asynchronously, while reject
is a callback. For example, some timeout:
new Promise(_, reject) {
setTimeout(reject, 1000);
});
Its exactly the same?
No, at least not when other code follows your statement. throw
immediately completes the resolver function, while calling reject
continues execution normally - after having "marked" the promise as rejected.
Also, engines might provide different exception debugging information if you throw
error objects.
For your specific example, you are right that p1
and p2
are indistinguishable from the outside.
js async/await throws error on using this keyword
You are creating a new function
return new Promise((resolve,reject)=>{
you should declare that function as async too:
return new Promise(async (resolve,reject)=>{
The new function will be
async function encodeName(x){
return new Promise(async (resolve,reject)=>{
const cipher = crypto.createCipher('aes192', this.PASSWORD);
let encrypted = cipher.update(x,'utf8', 'hex');
encrypted += cipher.final('hex');
if(encrypted.length>240){
let x = await this.storeFileName(encrypted);
resolve(`@Fn ${x}`);
}
resolve(encrypted);
});
}
Related Topics
How to Implement Prepend and Append with Regular JavaScript
Calling a JSON API with Node.Js
Chrome Extension: Port Error: Could Not Establish Connection. Receiving End Does Not Exist
Google Maps API - Getting Closest Points to Zipcode
How to Shuffle the Characters in a String in JavaScript
How to Sort an Array Without Mutating the Original Array
How to Inherit Old-Style Class from Ecmascript 6 Class in JavaScript
Why Is Proxy to a Map Object in Es2015 Not Working
Get Wrong Value in Data Attribute Jquery
New Line in JavaScript Alert Box
What Is Settimeout Doing When Set to 0 Milliseconds
Jquery - Script Tags in the HTML Are Parsed Out by Jquery and Not Executed
Why Use Object.Prototype.Hasownproperty.Call(Myobj, Prop) Instead of Myobj.Hasownproperty(Prop)
Firefox 'Cross-Origin Request Blocked' Despite Headers
Clearrect Function Doesn't Clear the Canvas
Jquery .On() Method with Multiple Event Handlers to One Selector