admin管理员组文章数量:1323348
Node 8.1.2, I have a structure where one file is calling another file's function in a map. In a real example I would use Promise.all
on the map
but that's not the question here. Here is the structure:
A.js:
const { b } = require('./B')
function expressStuff (req, res, next) {
things.map(thing => {
return b(thing)
}))
return res.status(200).json(...)
}
B.js:
// Thing -> Promise<Object>
function b (thing) {
return ThingModel.update(...) // this returns a Promise but FAILS and throws an errror
}
module.exports = { b }
OK. So in function b
I try to get some async data (from a database). It fails and throws an Uncaught Promise Rejection.
How to make deal with it?
I tried multiple solutions:
A1.js:
const { b } = require('./B')
function expressStuff (req, res, next) {
things.map(thing => {
try {
return b(thing)
} catch (err) {
return next(err)
}
}))
return res.status(200).json(...)
}
But that is still uncaught.
A2.js
:
const { b } = require('./B')
function expressStuff (req, res, next) {
try {
things.map(thing => {
return b(thing)
}))
} catch (err) {
return next(err)
}
return res.status(200).json(...)
}
Still unhandled. I tried using Promise.all
, I tried double try-catch blocks (since I thought the one inside map
might be returning next
from the to the map
result and not actually from expressStuff
function. Still nothing.
The closes I got to the answer was handling the error but then code wouldn't wait for it to be thrown and both res.status()
and next
would work resulting in race conditions and cannot set headers after they are sent
errors.
All I want to do is for the function b
to throw an error but catch it in the expressStuff
so I can rethrow custom UnprocessableEntityError
and pass it to next
. It seems like error from file B
is not bubbling up to the map
where it is called.
How do I do it?
EDIT:
The only way I can make this rejection handled is try-catching it in the B.js
. But if I try to rethrow an error/return it - nothing. Error is swallowed. If I try to console.log
it - it will be logged though.
DETAILS:
Thanks to marked answer I refactored my actual code and made it to work perfectly.
function expressStuff (res, req, next) {
try {
await Promise.all(things.map(async thing => {
if (ifSomething()) {
await b(thing)
}
}))
} catch (err) {
return next(new MyCustomError('My Custom Error Message'))
}
return res.status(200).json(...)
}
Node 8.1.2, I have a structure where one file is calling another file's function in a map. In a real example I would use Promise.all
on the map
but that's not the question here. Here is the structure:
A.js:
const { b } = require('./B')
function expressStuff (req, res, next) {
things.map(thing => {
return b(thing)
}))
return res.status(200).json(...)
}
B.js:
// Thing -> Promise<Object>
function b (thing) {
return ThingModel.update(...) // this returns a Promise but FAILS and throws an errror
}
module.exports = { b }
OK. So in function b
I try to get some async data (from a database). It fails and throws an Uncaught Promise Rejection.
How to make deal with it?
I tried multiple solutions:
A1.js:
const { b } = require('./B')
function expressStuff (req, res, next) {
things.map(thing => {
try {
return b(thing)
} catch (err) {
return next(err)
}
}))
return res.status(200).json(...)
}
But that is still uncaught.
A2.js
:
const { b } = require('./B')
function expressStuff (req, res, next) {
try {
things.map(thing => {
return b(thing)
}))
} catch (err) {
return next(err)
}
return res.status(200).json(...)
}
Still unhandled. I tried using Promise.all
, I tried double try-catch blocks (since I thought the one inside map
might be returning next
from the to the map
result and not actually from expressStuff
function. Still nothing.
The closes I got to the answer was handling the error but then code wouldn't wait for it to be thrown and both res.status()
and next
would work resulting in race conditions and cannot set headers after they are sent
errors.
All I want to do is for the function b
to throw an error but catch it in the expressStuff
so I can rethrow custom UnprocessableEntityError
and pass it to next
. It seems like error from file B
is not bubbling up to the map
where it is called.
How do I do it?
EDIT:
The only way I can make this rejection handled is try-catching it in the B.js
. But if I try to rethrow an error/return it - nothing. Error is swallowed. If I try to console.log
it - it will be logged though.
DETAILS:
Thanks to marked answer I refactored my actual code and made it to work perfectly.
function expressStuff (res, req, next) {
try {
await Promise.all(things.map(async thing => {
if (ifSomething()) {
await b(thing)
}
}))
} catch (err) {
return next(new MyCustomError('My Custom Error Message'))
}
return res.status(200).json(...)
}
Share
Improve this question
edited Jul 11, 2017 at 8:24
Tomasz Gałkowski
asked Jul 11, 2017 at 7:47
Tomasz GałkowskiTomasz Gałkowski
931 silver badge4 bronze badges
1 Answer
Reset to default 7Handling rejections with try
/catch
works only in async function
s when you await
the promise - which you haven't attempted yet.
You could do either
async function expressStuff (req, res, next) {
var results;
try {
results = await Promise.all(things.map(b)); // throws when any of the promises reject
} catch (err) {
return next(err) // handle error
}
return res.status(200).json(...)
}
or (like Wait until all ES6 promises plete, even rejected promises)
function expressStuff (req, res, next) {
const resultPromises = things.map(async (thing) => {
try {
return await b(thing); // throws when the promise for this particular thing rejects
} catch (err) {
return defaultValue; // handle error - don't call `next` here
}
});
…
return res.status(200).json(...)
}
本文标签: javascriptHandling Errors (Rejections) in asyncawait inside ArraymapStack Overflow
版权声明:本文标题:javascript - Handling Errors (Rejections) in asyncawait inside Array#map - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742133443a2422266.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论