Skip to content

Conversation

domenic
Copy link
Member

@domenic domenic commented Nov 10, 2016

This fixes #547, by marking the state promises (reader.closed, writer.closed, and writer.ready) as handled whenever they are rejected. It also overhauls the tests to handle all rejections, as apparently this will be enforced by testharness.js soon: see w3c/testharness.js@7716e25.

In the process, this adds additional test coverage for many rejections: since we have to handle them anyway, we might as well test them with promise_rejects. It also led to a fix to the completely-broken test "WritableStream should call underlying sink's close if no abort is supplied" in aborting.js. Finally, it uncovered an issue where ongoing write() calls would reject if abort() is called subsequently, even if the ongoing write succeeds according to the underlying sink.


This is not yet ready to merge as a test is still failing, for the write() + abort() case. It is the test "Aborting a WritableStream prevents further writes after any that are in progress", which I have updated to expect that the write() fulfills, but currently it fails with the aborted TypeError.

The problem is essentially that abort() synchronously rejects all pending write requests, whereas WritableStreamDefaultControllerProcessWrite does not unshift the pending write request until the underlying sink's write() call succeeds, which happens asynchronously.

We should instead unshift the pending write request the moment the underlying sink write() call is made, I think. This matches better the idea that once the underlying sink write() has started, it is entirely up to the underlying sink whether the writer.write() call should fulfill or reject. But a quick attempt to do that leads to lots of test timeouts and other failures. I would appreciate help investigating ways of making the test pass.

Alternately we could mark the test as skipped for now (I guess in WPT land that would mean commenting it out and filing an issue) just to get the promise rejection stuff underway.

@domenic domenic force-pushed the unhandled-rejections branch from 687f850 to 7a5f2ee Compare November 10, 2016 00:51

return promise_rejects(t, error1, writer.closed, 'writer.closed must reject with the write error')
return promise_rejects(t, error1, writer.write('Hello'), 'writer.write() must reject with the write error')
.then(() => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

How about doing without the {} here?

This fixes #547, by marking the state promises (reader.closed, writer.closed, and writer.ready) as handled whenever they are rejected. It also overhauls the tests to handle all rejections, as apparently this will be enforced by testharness.js soon: see w3c/testharness.js@7716e25.

In the process, this adds additional test coverage for many rejections: since we have to handle them anyway, we might as well test them with promise_rejects. It also led to a fix to the completely-broken test "WritableStream should call underlying sink's close if no abort is supplied" in aborting.js. Finally, it uncovered an issue where ongoing write() calls would reject if abort() is called subsequently, even if the ongoing write succeeds according to the underlying sink.
@domenic
Copy link
Member Author

domenic commented Nov 14, 2016

OK, this should be ready to go. Here is a proposed commit message:

Mark promise rejections for "state promises" as handled

This fixes #547, by marking the state promises (reader.closed, writer.closed, and writer.ready) as handled whenever they are rejected. It also overhauls the tests to handle all rejections, as apparently this will be enforced by testharness.js soon: see https://github.com/w3c/testharness.js/commit/7716e2581a86dfd9405a9c00547a7504f0c7fe94.

In the process, this adds additional test coverage for many rejections: since we have to handle them anyway, we might as well test them with promise_rejects. It also led to a fix to the completely-broken test "WritableStream should call underlying sink's close if no abort is supplied" in aborting.js. Finally, it uncovered an issue where ongoing write() calls would reject if abort() is called subsequently, even if the ongoing write succeeds according to the underlying sink; this led to temporarily commenting out the test "Aborting a WritableStream prevents further writes after any that are in progress", and opening #611 to track fixing that.

In terms of spec changes, this also discovered that WritableStreamDefaultWriter was returning rejected promises that its caller had no use for. This has been fixed as well.

@ricea
Copy link
Collaborator

ricea commented Nov 15, 2016

lgtm

@domenic domenic merged commit 0745219 into master Nov 15, 2016
@domenic domenic deleted the unhandled-rejections branch November 15, 2016 03:57
@tyoshino
Copy link
Member

tyoshino commented Jan 6, 2017

I found that the reference implementation will be readable and easier to maintain if we move the .catch(() => {}) to the promise fulfilling/rejecting/resetting helper functions ( 41c46c2 ).

I attempted to do this refactoring, but noticed that considering that the purpose of the reference implementation is for checking the correctness of the specification, it might be better to keep .catch(() => {}) placed right next to each helper function invocation to keep them in sync with the spec text.

Thoughts? If you agree, I just do nothing.

@ricea
Copy link
Collaborator

ricea commented Jan 6, 2017

@tyoshino I already had this conversation inside my head. Maybe I should have mentioned it to someone else. Anyway, I came to the same conclusion that you did: that it's important to do the steps in the same order and granularity as the standard, even if it sometimes makes the reference implementation a bit unnatural.

@tyoshino
Copy link
Member

tyoshino commented Jan 6, 2017

@ricea Thanks. Then ok!

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

Successfully merging this pull request may close these issues.

Marking promise rejections as handled
3 participants