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

fix: replace pify with simpler promise helpers #221

Merged
merged 1 commit into from
Feb 8, 2018
Merged

fix: replace pify with simpler promise helpers #221

merged 1 commit into from
Feb 8, 2018

Conversation

filipesilva
Copy link
Contributor

pify seems to not be working correctly when a decorated file system is used as inputFileSystem.

Fix #217

@@ -0,0 +1,10 @@
export default function readFilePromise(inputFileSystem, path) {
Copy link
Member

Choose a reason for hiding this comment

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

src/utils/promisify.js

export const stat = ...
export const readFile = ...
import { stat, readFile } from './utils/promisify';

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@michael-ciniawsky michael-ciniawsky added this to the 4.4.1 milestone Feb 8, 2018
Copy link
Member

@alexander-akait alexander-akait left a comment

Choose a reason for hiding this comment

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

Thanks for help!

@michael-ciniawsky michael-ciniawsky changed the title fix: replace pify with a simpler promise helper fix: replace pify with a simpler promise helpers Feb 8, 2018
@michael-ciniawsky michael-ciniawsky changed the title fix: replace pify with a simpler promise helpers fix: replace pify with simpler promise helpers Feb 8, 2018
`pify` seems to not be working correctly when a decorated file system is used as `inputFileSystem`.

Fix #217
Copy link
Member

@michael-ciniawsky michael-ciniawsky left a comment

Choose a reason for hiding this comment

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

@jcyovera
Copy link

jcyovera commented Feb 8, 2018

Thank you for the fix!

@filipesilva filipesilva deleted the replace-pify branch February 8, 2018 15:18
@kabe5965
Copy link

kabe5965 commented Feb 8, 2018

New version 4.4.1 did it! Thanks! Deploy to Heroku works as well.

@filipesilva
Copy link
Contributor Author

@evilebottnawi looked a bit more into why pity was not working with the decorated file system. It turns out pify uses for (const key in obj) { } to iterate over the object, but the decorated file system function were not enumerable and thus did not show up there.

For the decorated file system in Angular CLI we used a TypeScript class, which downlevels to a ES6 class. It seems pify does not work with ES6 class instances. I opened an issue for it in sindresorhus/pify#57.

@sindresorhus
Copy link

I don't understand why the fix is so overcomplicated though. You could have just used pify on the individual methods.

@filipesilva
Copy link
Contributor Author

@sindresorhus in hindsight, that would have been a great solution. At the time I did not know only one of the pify modes of operation had problems with ES6 classes.

We were looking at getting a fix in since it was affecting a lot of users in angular/angular-cli#9550. After fixing the issue proper I went to report the issue on pify with a repro and found out that the other usage mode was ok.

inputFileSystem.stat(path, (err, stats) => {
if (err) {
reject(err);
}

Choose a reason for hiding this comment

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

Without an else or early return statement, resolve will even be called in the case of a rejection. Same is the case for readFile below.

Copy link
Member

Choose a reason for hiding this comment

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

@ronkorving reject already do early exit, no necessary return

Choose a reason for hiding this comment

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

How can it? To my knowledge, the only way to return early in JS is return or throw.
reject(err) is just a function call.

Copy link
Member

Choose a reason for hiding this comment

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

@ronkorving reject() === throw inside promise

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is true that resolve(stats) will still be called, but the stats value will not be passed on to anything. Even if there is another promise waiting for the resolve value, the rejection path will be taken instead.

It's a still a bug though, in the sense that it was never intended for the resolve to run in the first place.

@evilebottnawi WDYT of me doing another PR that adds back pify with the alternative syntax that works on ES6 classes?

Copy link
Member

Choose a reason for hiding this comment

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

@ronkorving IMHO, return here need only for easy reading and understanding code. Feel free to PR if this confusing for you

Choose a reason for hiding this comment

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

@evilebottnawi I don't think I'm confused. As @filipesilva also pointed out, resolve(stats) will still be called.

I'll leave it to you both to figure out the way forward, given that there seems to be a desire to put pify back in anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried #228 but just using pify on the single method doesn't seem to work well either, this seems to be undefined when doing that so class members aren't accessible.

@ronkorving would you like to make a PR to change the if to a if ... else?

Copy link
Member

@michael-ciniawsky michael-ciniawsky Feb 15, 2018

Choose a reason for hiding this comment

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

if (err) reject(err) // I'm not 100% here, but this should be === (x) => x (return)

resolve(x)
if (err) {
   return reject(err)
}

resolve(x)
if (err) {
   reject(err)
   // eventually to guard against 'runaway' promises
   return null
}

resolve(x)

Please no extra lib, it's not necessary to promisify two callback functions :)

Copy link
Member

Choose a reason for hiding this comment

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

@ronkorving Thx. Nice catch :)

@ronkorving
Copy link

I noticed what I believe to be a bug in this PR and left a comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants