I have a Promise method that parses links from the web. It returns an Object which I try to access a link
key from, but when this Object is empty, it somehow skips the if
I have to check its length, causing a scandalous error. Below the codes.
First, the method that is a Promise to parse the links:
* parseReporter() {
const article = new Promise((resolve, reject) => {
parser.parseURL(`https://www.google.com/alerts/feeds/${this.googleAlertsUrlId}/${this.reporterUrlId}`, (err, parsed) => {
if (err) {
reject(new Error(err))
}
if (parsed.feed.entries.length === 0) {
reject(new Error('Nothing to parse'))
}
const link = parsed.feed.entries[0].link
const betterLink = link.substring(42, link.indexOf('&ct='))
mercury.parse(betterLink).then((data) => {
resolve(data)
}).catch((err) => {
reject(new Error(err))
})
})
})
return article
}
And then, here's the method that calls this parseReporter()
:
* _getLastestNews(userReporter) {
const reportersOperation = new ReportersOperation()
reportersOperation.googleAlertsUrlId = userReporter.url.split('/')[3]
reportersOperation.reporterUrlId = userReporter.url.split('/')[4]
try {
return yield reportersOperation.parseReporter()
} catch (e) {
this.addError(HTTPResponse.STATUS_INTERNAL_SERVER_ERROR, e.message)
return false
}
}
The error is caused when it tries to access link
from parsed.feed.entries[0]
. I've already logged out the length
, and I confirmed to do work and show a number, but it insists on skipping it. Am I doing something wrong with the Promise it try/catch
themselves?
reject
doesn't "stop" or "return" from a function like return
Therefore, your code is checking for error conditions, but continuing on, as if the data is OK
By adding return
before the call to reject
, you'll stop this from happening
Just the area of code with changes shown:
// snip
if (err) {
return reject(new Error(err))
}
if (parsed.feed.entries.length === 0) {
return reject(new Error('Nothing to parse'))
}
const link = parsed.feed.entries[0].link
const betterLink = link.substring(42, link.indexOf('&ct='))
//snip
Besides, what Jaramonda suggested, you're also using an anti-pattern when you have a promise and you do resolve and reject in both paths. You can do that much more efficiently:
resolve(mercury.parse(betterLink));
But, what you really should do is you should promisify parser.parseURL()
so you can write all the control flow logic using promises. This is much more foolproof and creates a reusable interface that uses promises that you can use elsewhere:
// make promisified version of parser.parseURL()
parser.parseURLP = function (url) {
return new Promise((resolve, reject) => {
parser.parseURL(url, (err, parsed) => {
if (err) return reject(new Error(err));
resolve(parsed);
});
});
};
function parseReporter() {
return parser.parseURL(`https://www.google.com/alerts/feeds/${this.googleAlertsUrlId}/${this.reporterUrlId}`).then(parsed => {
if (parsed.feed.entries.length === 0) {
throw new Error('Nothing to parse');
}
const link = parsed.feed.entries[0].link
const betterLink = link.substring(42, link.indexOf('&ct='))
return mercury.parse(betterLink).catch(err => {
// wrap error in Error object
throw new Error(err);
})
})
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.