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

remove error-inject and fix error handling #1409

Merged
merged 6 commits into from May 16, 2020
Merged

remove error-inject and fix error handling #1409

merged 6 commits into from May 16, 2020

Conversation

tinovyatkin
Copy link
Contributor

@tinovyatkin tinovyatkin commented Oct 17, 2019

The whole error-inject functionality (it's 3 lines actually) is to add error event listener as on listener, while working around the fact that Node doesn't check if that handler already exists, so, that check was added.

However, by obscuring this logic in 3 lines module even module author @dead-horse probably forgot what exactly his module is doing while introducing #800, which basically rendered this check useless by creating inline function.

To prevent this to happen again, and also taking into account that ctx.onerror calls res.end and so, .once is the more appropriate listener, I'm proposing removing error-inject dependency and use the fact that respond body assignment already has logic to make something once per stream.

@codecov
Copy link

codecov bot commented Oct 17, 2019

Codecov Report

Merging #1409 into master will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #1409   +/-   ##
=======================================
  Coverage   99.38%   99.38%           
=======================================
  Files           4        4           
  Lines         484      484           
  Branches      130      131    +1     
=======================================
  Hits          481      481           
  Partials        3        3           
Impacted Files Coverage Δ
lib/response.js 99.37% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 143d8f7...e85c77a. Read the comment docs.

// overwriting
if (null != original && original != val) this.remove('Content-Length');
if (original != val) {
val.once('error', err => this.ctx.onerror(err));
Copy link
Member

Choose a reason for hiding this comment

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

The two implementations seem to be not equal. We should only add error event listener when the stream has no other error event listener, which aim to avoid uncaught exception.

Also IMO koa's code philosophy is to keep code simple, so we don't treat 'one-liner module' as a bad thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In current implementation the check in the error-inject does nothing (as two inline created functions never the same) and just always add .on('error') handler. Do you mean that was desired behaviour?
I'm proposing to remove error-inject here not because it's one line, but because even you (module author) forgot that you are breaking it functionality while refactored to inline function. It just does nothing in current version.

Copy link
Member

Choose a reason for hiding this comment

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

i don't understand what you mean, can you explain in a test?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jonathanong Sorry for my English. I've added a failing test to this PR, it's pretty simple:

it('should add error handler to the stream, but only once', () => {
      const res = response();
      const body = new Stream.PassThrough();
      assert.strictEqual(body.listenerCount('error'), 0);
      res.body = body;
      assert.strictEqual(body.listenerCount('error'), 1);
      res.body = body;
      assert.strictEqual(body.listenerCount('error'), 1);
    });

This fails in Koa master and passing after merging this PR.

Copy link
Member

Choose a reason for hiding this comment

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

seems like a developer error

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, but the most probable explanation here is that by hiding the actual logic in a one-line module even the author of the module forgot the logic on a next refactoring and broke the functionality. That's what this PR is all about - fix the error and bring the logic inside to prevent such a problem in the future.

Copy link
Member

@fengmk2 fengmk2 left a comment

Choose a reason for hiding this comment

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

I don't think we should change this in any reason.

@tinovyatkin
Copy link
Contributor Author

tinovyatkin commented Oct 19, 2019

I don't think we should change this in any reason.

@fengmk2 Why, if there is an error?

@@ -108,6 +109,16 @@ describe('res.body=', () => {
res.body = fs.createReadStream('LICENSE');
assert.equal('application/octet-stream', res.header['content-type']);
});

it('should add error handler to the stream, but only once', () => {
Copy link
Member

Choose a reason for hiding this comment

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

This test case clearly shows where the problem is, LGTM

@dead-horse dead-horse merged commit faeaff5 into koajs:master May 16, 2020
@tinovyatkin tinovyatkin deleted the remove-error-inject branch May 16, 2020 20:09
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.

None yet

4 participants