Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #525: Add eslint-plugin-promise and fix async/Promise issues #527

Merged
merged 1 commit into from
Jan 21, 2020

Conversation

c3ho
Copy link
Contributor

@c3ho c3ho commented Dec 21, 2019

Issue This PR Addresses

Type of Change

  • Bugfix: Change which fixes an issue
  • New Feature: Change which adds functionality
  • Documentation Update: Change which improves documentation
  • UI: Change which improves UI

Description

Added eslint rules regarding promises, we have promises that have catches and returns and some don't. These rules ensure consistency

Checklist

  • Quality: This PR builds and passes our npm test and works locally
  • Tests: This PR includes thorough tests or an explanation of why it does not
  • Screenshots: This PR includes screenshots or GIFs of the changes made or an explanation of why it does not (if applicable)
  • Documentation: This PR includes updated/added documentation to user exposed functionality or configuration variables are added/changed or an explanation of why it does not(if applicable)

@c3ho
Copy link
Contributor Author

c3ho commented Dec 21, 2019

Having issues with dealing with inactive-blog-filter.js. It returns a lot of promises.

@manekenpix manekenpix changed the title Issue 525 Fixes #525: Add eslint-plugin-promise and fix async/Promise issues Dec 23, 2019
Copy link
Member

@manekenpix manekenpix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a comment for the misspelled rule. Going to review the errors now.

.eslintrc.js Outdated Show resolved Hide resolved
@c3ho
Copy link
Contributor Author

c3ho commented Dec 23, 2019

I think all the functions in storage.js are/should be async no?

@manekenpix manekenpix added the developer experience Helping the Developer Experience label Dec 23, 2019
@c3ho
Copy link
Contributor Author

c3ho commented Jan 11, 2020

Running npm test will fail on the wiki-feed-parser.test
image

Otherwise it passes every test. Please go easy on me.

@manekenpix
Copy link
Member

Tests pass for me.

@manekenpix manekenpix self-requested a review January 11, 2020 16:17
Copy link
Contributor

@humphd humphd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, cookie monster. I have done a first read through this, and made some notes for things to fixup or improve. When you've done these, and it's passing CI, we can do another round.

Thanks for doing this! I think it will help people a lot when it's in to avoid making mistakes. You should plan to do a short learning session for the rest of the team to teach them some of the patterns and anti-patterns this revealed as you went.

.eslintrc.js Show resolved Hide resolved
@@ -42,6 +42,7 @@ async function enqueueWikiFeed() {
enqueueWikiFeed()
.then(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Often this means you can just rely on the implicit return value you get with an arrow function. I think this is better:

.then(() => feedWorker.start())

}
});
this.getAsyAnalysis = function() {
let result;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop this result arg, and just use return on every line where you set result below. Return early, return often.

@@ -90,18 +90,16 @@ exports.sendMessage = async function(receipiants, subjectMessage, message) {
);
const allGood = this.verifyTransporter(transporter);
if (!allGood) {
reject(new Error()); // Send promise.reject if an error occurs
logger.error(new Error());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get rid of the variable, add a message to the error so it's useful, throw.

if(!this.verifyTransporter(transporter)) {
  throw new Error('email transport could not be verified');
}

.then(res => res.json())
.then(data => {
let fetchedData;
const fetchResult = await fetch(`${githubAPI}${subUrl}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fetch can throw, so can .json(), so we should wrap these in try/catch.

@@ -68,5 +68,8 @@ module.exports = {

getPostsCount: () => redis.zcard(POSTS),

getPost: async guid => redis.hgetall(guid),
getPost: async guid => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for async/await here, this already returns a Promise.

getPost: guid => redis.hgetall(guid)

test/email-sender.test.js Outdated Show resolved Hide resolved
@@ -1,5 +1,6 @@
const feedparser = require('feedparser-promised');
const checkForSpam = require('../src/backend/utils/spam-checker');
// const { logger } = require('../src/backend/utils/logger');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this if not needed.

@@ -81,7 +82,13 @@ describe('Storage tests for posts', () => {
};

beforeAll(() => {
Promise.all([testPost, testPost2, testPost3].map(post => addPost(post)));
Promise.all([testPost, testPost2, testPost3].map(post => addPost(post)))
.then(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we mixing async/await and .then? Do we really need this .then at all?

Copy link
Contributor

@humphd humphd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting there. I did another pass over it. It's looking really good, great work.

.eslintrc.js Show resolved Hide resolved
src/backend/utils/basic_analysis.js Outdated Show resolved Hide resolved
src/backend/utils/github-url.js Outdated Show resolved Hide resolved
}
return fetchedData;
} catch (error) {
throw new Error('Error fetching data');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If all you're going to do in a .catch is throw, there's no value in doing it, and you can just leave it off. However, it might be nice to log the error here, before you throw it. Also, I'd consider just re-throwing the actual error vs. making your own, and losing the original error message and stack.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What you do in src/backend/utils/inactive-blog-filter.js below is what I mean.

src/backend/utils/storage.js Outdated Show resolved Hide resolved
test/inactive-blog-filter.test.js Outdated Show resolved Hide resolved
test/inactive-blog-filter.test.js Outdated Show resolved Hide resolved
test/inactive-blog-filter.test.js Show resolved Hide resolved
test/posts.test.js Outdated Show resolved Hide resolved
test/storage.test.js Outdated Show resolved Hide resolved
Copy link
Contributor

@humphd humphd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few minor things left, otherwise, this looks great.


const log = logger.child({ module: 'github-url' });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not do this. The docs suggest it, but for our needs, it's not really necessary to isolate logs into sub-modules at this stage. Just use logger.info(), etc.

try {
const redListRaw = await fsPromises.readFile(redlistPath, 'utf-8');
const redList = [].concat(JSON.parse(redListRaw));
return redList.some(isRedlisted.bind(null, feedUrl));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this not be return redList.some(redItem => isRedlisted(feedUrl, redItem));? It doesn't seem like we need to .bind() here.

.eslintrc.js Show resolved Hide resolved
@humphd
Copy link
Contributor

humphd commented Jan 19, 2020

@c3ho did you ever fix your error above in #527 (comment)? It means you need to rebuild some binary dependency that was linked against header files for a different version of node/v8. If you update node, you sometimes have to rebuild. There's a command to do it, or you can rm -fr node_modules && npm install.

@c3ho
Copy link
Contributor Author

c3ho commented Jan 19, 2020

@humphd it is flaky for me on Windows. Sometimes it passes with no issues, sometimes I run into the error. I've done what you've usually suggested in OSD600 removing the dependency folders and everything. I've even tried installing nvm on my windows machine. I tested this on Mac and there were no issues.

Copy link
Contributor

@humphd humphd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last set of small fixes, and this is ready, I think. Great work, @c3ho. Let's get this in!

const result = await transporter.sendMail(mail);
return result.accepted;
} catch (error) {
logger.error(error);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logger.error({ error }, 'Unable to send email');

const fetchResult = await fetch(`${githubAPI}${subUrl}`);
data = await fetchResult.json();
} catch (error) {
logger.error(error);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logger.error({ error }, 'Unable to fetch GitHub API results');

try {
const redListRaw = await fsPromises.readFile(redlistPath, 'utf-8');
const redList = [].concat(JSON.parse(redListRaw));
// return redList.some(isRedlisted.bind(null, feedUrl));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this if it's just commented out.

@@ -24,8 +24,8 @@ describe('test /posts endpoint', () => {
};
});

beforeAll(() => {
Promise.all(posts.map(post => addPost(post)));
beforeAll(async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jest's functions work async if you return a Promise, so you can change this to:

beforeAll(() => Promise.all(posts.map(post => addPost(post))));

@@ -120,8 +120,8 @@ describe('test /posts/:guid responses', () => {

// add the post to the storage
beforeAll(async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

beforeAll(() => Promise.all([addedPost1.save(), addedPost2.save()]));

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one got missed.

@@ -80,8 +80,8 @@ describe('Storage tests for posts', () => {
site: 'foo',
};

beforeAll(() => {
Promise.all([testPost, testPost2, testPost3].map(post => addPost(post)));
beforeAll(async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

beforeAll(() => Promise.all([testPost, testPost2, testPost3].map(post => addPost(post))));

Copy link
Contributor

@humphd humphd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of my previous comments got missed, after that, this is good to go.

@@ -120,8 +120,8 @@ describe('test /posts/:guid responses', () => {

// add the post to the storage
beforeAll(async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one got missed.

@c3ho
Copy link
Contributor Author

c3ho commented Jan 21, 2020

@humphd if this is good to go, I'm going to rebase again and resubmit, VSC was going weird on me and added your recent code as part of my PR

Copy link
Contributor

@humphd humphd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is failing tests, can you fix and let me know when it's green?

@c3ho
Copy link
Contributor Author

c3ho commented Jan 21, 2020

@humphd its failing on this one
image

Is the fix just a simple await in front of queue.add() (line 33)?

@humphd
Copy link
Contributor

humphd commented Jan 21, 2020

I filed #567 to deal with the problem of knowing whether something returns a Promise or not.

Copy link
Contributor

@humphd humphd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done.

Copy link
Member

@manekenpix manekenpix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@c3ho c3ho merged commit f185fcf into Seneca-CDOT:master Jan 21, 2020
@c3ho c3ho deleted the issue-525 branch January 21, 2020 20:14
@humphd
Copy link
Contributor

humphd commented Jan 21, 2020

Yeah, merged!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
developer experience Helping the Developer Experience
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants