Skip to content

Mega PR: unhandledRejection, uncaughtException, reliable IO capture, consistent tests. #206

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

Merged
merged 5 commits into from
Nov 16, 2015

Conversation

jamestalmage
Copy link
Contributor

Combination of other PR's: #211, #213, #215

It adds the following features:

  • Reporting of uncaught exceptions in forked processes.
  • Reporting of unhandled promise rejections in forked processes.
  • Increased likelihood of receiving and printing all data from forked process stdout and stderr.
  • Improved reliability of stdout/stderr capture in AppVeyor CI by detecting AppVeyor and slowing down process.exit events.
  • Since the above solution is not perfect, increase likelihood of passing tests on AppVeyor by running the tests a second time if they fail.

I have some ideas for refactoring that might make some of this cleaner, but I know there are a number of pending PR's, and I don't want to go crazy until those land.

@jamestalmage jamestalmage force-pushed the use-loud-rejection branch 4 times, most recently from 6585856 to cfbba40 Compare November 15, 2015 04:48
@jamestalmage jamestalmage changed the title wip - Report unhandledRejections Mega PR: unhandledRejection, uncaughtException, reliable IO capture, consistent tests. Nov 15, 2015
// TODO: figure out why this needs to be here to
// correctly flush the output when multiple test files
process.stdout.write('');
process.stderr.write('');
Copy link
Member

Choose a reason for hiding this comment

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

Wut, another one? :p

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, there's 3 of process.stdout.write('') now for no explained reason.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oops - I meant to delete that other one.

There should be one each stderr and stdout. This belongs in the "it seamed to help" pile. Definitely room to experiment with removing it down the road.

@sindresorhus
Copy link
Member

Why combine the unhandledRejection/uncaughtException stuff with the rest? Seems it could be a separate PR? Or is there a coupling with the other fixes?


var endPromise = Promise.all([promise.reflect(), stdout, stderr]).then(function () {
Copy link
Member

Choose a reason for hiding this comment

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

This is weird. Why not just wait on ps.on('exit')?

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've come at this at least 5 times, and every time, it has required all these fixes.

I don't know that I've ever applied this one last, so it could be unnecessary. I can pull it out with another commit and see what happens.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

#219 will tell us if this was necessary.

@sindresorhus
Copy link
Member

// @vdemedes @floatdrop

@jamestalmage
Copy link
Contributor Author

Why combine the unhandledRejection/uncaughtException stuff with the rest? Seems it could be a separate PR?

The uncaught exception stuff is definitely coupled. These all started as separate PR's (see description).

@jamestalmage
Copy link
Contributor Author

My preference would be to get this merged so everybody can start getting green PR's again. I can then work backwards and see what can be pulled out. Working backwards from green is going to be easier than going the other direction.

Tests are just too brittle on AppVeyor. `npm install` fails frequently,
and Node on Windows does not seem to reliably flush stdout/stderr
of forked child processes.

I don't like this, but I'm at a loss for other solutions.
wait for forked streams to end before resolving promise
(cherry picked from commit 4539ccc)

wait for io streams to end even when fork promise is rejected
(cherry picked from commit 6bff82a)
add small delay on exit from babel
(cherry picked from commit 11961f7)

if AVA is not required in a test, throw an error instead of process.exit

only extend timeout if env.AVA_APPVEYOR is set, so we only slow down
in our tests.
@jamestalmage
Copy link
Contributor Author

Just Sayin...

screenshot 2015-11-16 01 18 19

@jamestalmage
Copy link
Contributor Author

@sindresorhus
Every comment except the separating out loud-rejection promises is addressed.

I think I can pull it out if you really think it is necessary. I think we will still have reliable builds without it.

@floatdrop
Copy link
Contributor

Great work! - reliable builds on Windows is must have. Rough edges can be improved from there.

I'm think that unhandled related code (and serialize-value replacement too?) --should-- could be moved in separate PR - it will be easier to find corresponding code to fixes later. Not critical thou.

@jamestalmage
Copy link
Contributor Author

serialize-value is part of the fix for uncaught exceptions, and that is part of the solution for reliable builds. Allowed to go uncaught, they cause the child to exit unpredictably (we are not sure exactly what messages the parent has received). With this we notify parent "hey, uncaught error here, bailing!", wait for acknowledgement, and then shut down. Otherwise we must rely on stderr / stdout from the child to be properly piped to stderr/stdout on the parent. For reasons unknown to me, that is just too unreliable on Windows to be a solution.

Unfortunately, I committed the unhandled-rejection stuff before the uncaught-exception, and there a number of conflicts between the two (here, here, etc.). Part of the frustration was that everything passed on my machine, yet failed on AppVeyor. Scroll through the AppVeyor history if you wanna see my name 3 dozen times next to a lot of red 😠. It is probably not a huge deal to pull out the unhandled rejection stuff, but there will be merge conflicts to resolve before and after, and it just seems like extra work for not a lot of benefit.

I think I did do a pretty good job maintaining a good git history, and have squashed relevant commits together. Perhaps do not squash this PR so git blame and the commit log maintain finer grained details for each change?

@floatdrop
Copy link
Contributor

@jamestalmage no offence at all (sorry if it seems so, English is not my strongest part), really appreciate work you done in ava and related modules. I understand, that rebasing unhandledRejection is hard and not insisting on it. Thanks for explaining serialize-value part.

@jamestalmage
Copy link
Contributor Author

no offence

none taken 😄

The only thing that has offended me during this process is Windows!

execCli('fixture/uncaught-exception.js', function (err, stdout, stderr) {
t.ok(err);
t.ok(/Can't catch me!/.test(stderr));
// TODO: This should get printed, but we reject the promise (ending all tests) instead of just ending that one test and reporting.
Copy link
Member

Choose a reason for hiding this comment

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

For TODO's I prefer to include the username so we know who added it without having to git blame.

TODO(jamestalmage):

Copy link
Contributor Author

Choose a reason for hiding this comment

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

cool, I'm assuming you took care of it in the merge? Or do you want me to go handle it now?

Copy link
Member

Choose a reason for hiding this comment

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

I'll do it.

@sindresorhus
Copy link
Member

Looks good to me. Let's get this merged asap. Just waiting for @vdemedes to review.

@@ -18,6 +18,10 @@ module.exports = function (args) {

var ps = childProcess.fork(babel, args, options);

function send(command, data) {
ps.send({'ava-child-process-command': command, 'data': data});
Copy link
Contributor

Choose a reason for hiding this comment

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

can just be:

ps.send({
  name: command,
  data: data
});

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My only thought there was wether or not we wanted to monkeypatch process.on on the child process, so users never saw our communication.

I can imagine a scenario where you are writing some code that might be a child process (or might be top level), and so they would will listen to process.on('message'). By choosing a unique property name here we could monkeypatch on and filter out these messages. I reemit these on the child process as specific ava- prefixed events(process.on('ava-kill', ...), process.on('ava-cleanup'), etc) - that it is really unlikely users will listen to.

None of that is implemented. Just leaving the door open.

sindresorhus added a commit that referenced this pull request Nov 16, 2015
Mega PR: unhandledRejection, uncaughtException, reliable IO capture, consistent tests.
@sindresorhus sindresorhus merged commit b24b2ea into avajs:master Nov 16, 2015
@sindresorhus
Copy link
Member

Landed! Superb work tracking down all these issues @jamestalmage :)

I would honestly have just given up and removed AppVeyor :p

@jamestalmage jamestalmage deleted the use-loud-rejection branch November 16, 2015 11:25
@jamestalmage
Copy link
Contributor Author

Awesome!

I would honestly have just given up and removed AppVeyor :p

Now you tell me!! 😉

@sindresorhus
Copy link
Member

Now you tell me!! 😉

Automated Windows testing is especially important for a test runner, though, so glad we have it, regardless of what I feel about Windows.

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

Successfully merging this pull request may close these issues.

6 participants