await is only valid in async function - when using mongoosejs exec()
Solution 1
await
can only be used INSIDE a function that is declared with the async
keyword.
async function doSomething() {
let result = await someMongoooseFunctionThatReturnsAPromise();
// use result here
}
await
cannot be used outside an async
function. That's what your error is telling you and it has nothing to do with mongoose at all. It has to do with the structure of YOUR code that is calling the mongoose function.
NOTE: Any node.js event driven code is ALREADY inside a function so to use await
in that function, all you have to do is to add the async
keyword to that containing function definition. If the caller of that function is not expecting any return result, then no further changes are required. If the caller of that funcition is expecting a return result, then you have to adapt the calling code to expect a promise to be returned from the async
declared function.
It's also worth understanding that an async
function ALWAYS returns a promise. While you may write it like regular sequential code:
async function doSomething() {
let result = await someMongoooseFunctionThatReturnsAPromise();
// use result here
result++;
return result;
}
This function is actually returning a promise and the resolved value of that promise will be the return value of the function. So, when you use an async
function like this, you have to use the returned promise:
doSomething().then(finalResult => {
console.log(finalResult);
});
So, in your specific code, if you're going to use await
, it needs to be inside an async
function:
async function someFunc() {
const result = await User.findOne({email: email}).exec();
// now this will work and you can use result here
}
Alternatively, you can use .then()
instead:
User.findOne({email: email}).exec().then(result => {
// process result here
// continue with other code that uses result here
});
NOTE: To handle errors when using async/await
, you have two choices:
You can use traditional
try/catch
inside anyasync
declared function and thetry/catch
will catch any rejected promises fromawait
.If you don't use try/catch and an
await
inside your function rejects, then the promise that the function itself returns will become rejected and the caller of your function will get the rejected promise.
So, it depends upon the situation. If you want to handle a rejection locally, then you must use try/catch around await
(much like you would with .catch()
. If you want the rejecting to bubble up to the caller so they will see the rejected promise, then you don't need the try/catch
as the Javascript interpreter will automatically bubble a rejected await
by rejecting the promise that the async
function returns.
Solution 2
You need to surround your code in an async function like this
async function fetchFun() {
const result = await User.findOne({email: email}).exec();
console.log('Results fetched!'); //etc
}
fetchFun(); // <--
Note: You still have to call this function without await
as I pointed out by arrow because there has to be some entrance to your code async/await code (like main()
in C) and that entrance function cannot be called with await

cgiacomi
Updated on June 27, 2022Comments
-
cgiacomi 3 months
I am porting a Hapi project to v17 and running into some issues with Mongoose when moving to async/await.
With any of my code that uses 'await', on a model (mongoose), object for example:
const result = await User.findOne({email: email}).exec();
I get the following exception when running 'node server.js'
await User.findOne({}).exec(); ^^^^^ SyntaxError: await is only valid in async function at new Script (vm.js:74:7) at createScript (vm.js:246:10) at Object.runInThisContext (vm.js:298:10) at Module._compile (internal/modules/cjs/loader.js:670:28) at Object.Module._extensions..js (internal/modules/cjs/loader.js:713:10) at Module.load (internal/modules/cjs/loader.js:612:32) at tryModuleLoad (internal/modules/cjs/loader.js:551:12) at Function.Module._load (internal/modules/cjs/loader.js:543:3) at Module.require (internal/modules/cjs/loader.js:650:17) at require (internal/modules/cjs/helpers.js:20:18)
I am running node v10.2.0 and mongoose 5.1.2 and cannot understand why I am getting the error.
The mongoosejs documentation clearly states that one should use exec() to return the promise when using async/await as stated here
Any suggestions?