Skip to content

Commit fbe7a31

Browse files
committed
fixup
1 parent eebec50 commit fbe7a31

File tree

3 files changed

+32
-18
lines changed

3 files changed

+32
-18
lines changed

lib/_stream_writable.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@ const {
3939
module.exports = Writable;
4040

4141
const Stream = require('stream');
42-
const { WritableBase } = require('internal/streams/base');
42+
const {
43+
WritableBase,
44+
WritableStateBase,
45+
errorOrDestroy
46+
} = require('internal/streams/base');
4347

4448
const {
4549
getHighWaterMark,
@@ -54,7 +58,7 @@ const {
5458
function nop() {}
5559

5660
const kFlush = Symbol('kFlush');
57-
class WritableState extends WritableBase.WritableState {
61+
class WritableState extends WritableStateBase {
5862
constructor(options, stream, isDuplex) {
5963
super(options);
6064

@@ -203,11 +207,12 @@ function Writable(options) {
203207

204208
WritableBase.call(this, {
205209
...options,
206-
start: (stream, state) => {
210+
start: function() {
211+
const state = this._writableState;
207212
if (!state.writing) {
208-
clearBuffer(stream, state);
213+
clearBuffer(this, state);
209214
}
210-
finishMaybe(stream, state);
215+
finishMaybe(this, state);
211216
},
212217
write: writeOrBuffer,
213218
flush: function(state, cb) {
@@ -305,7 +310,7 @@ function onwriteError(stream, state, er, cb) {
305310
// writes.
306311
errorBuffer(state, new ERR_STREAM_DESTROYED('write'));
307312
// This can emit error, but error must always follow cb.
308-
WritableBase.errorOrDestroy(stream, er);
313+
errorOrDestroy(stream, er);
309314
}
310315

311316
function onwrite(stream, er) {
@@ -314,7 +319,7 @@ function onwrite(stream, er) {
314319
const cb = state.writecb;
315320

316321
if (typeof cb !== 'function') {
317-
WritableBase.errorOrDestroy(stream, new ERR_MULTIPLE_CALLBACK());
322+
errorOrDestroy(stream, new ERR_MULTIPLE_CALLBACK());
318323
return;
319324
}
320325

lib/internal/streams/base.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const {
1616
ERR_STREAM_CANNOT_PIPE,
1717
ERR_STREAM_DESTROYED,
1818
ERR_STREAM_ALREADY_FINISHED,
19+
ERR_MULTIPLE_CALLBACK,
1920
ERR_STREAM_NULL_VALUES,
2021
ERR_STREAM_WRITE_AFTER_END,
2122
ERR_UNKNOWN_ENCODING
@@ -74,6 +75,10 @@ class WritableStateBase {
7475

7576
// Indicates whether the stream has finished destroying.
7677
this.closed = false;
78+
79+
// True if close has been emitted or would have been emitted
80+
// depending on emitClose.
81+
this.closeEmitted = false;
7782
}
7883
}
7984

@@ -98,8 +103,6 @@ function WritableBase(options, isDuplex, State) {
98103
destroyImpl.construct(this, options.start);
99104
}
100105
WritableBase.prototype = ObjectCreate(Stream.prototype);
101-
WritableBase.errorOrDestroy = errorOrDestroy;
102-
WritableBase.WritableState = WritableStateBase;
103106
WritableBase.prototype.write = function(chunk, encoding, cb) {
104107
const state = this._writableState;
105108

@@ -108,6 +111,8 @@ WritableBase.prototype.write = function(chunk, encoding, cb) {
108111
encoding = state.defaultEncoding;
109112
} else if (!encoding) {
110113
encoding = state.defaultEncoding;
114+
} else if (encoding !== 'buffer' && !Buffer.isEncoding(encoding)) {
115+
throw new ERR_UNKNOWN_ENCODING(encoding);
111116
}
112117

113118
if (chunk === null) {
@@ -178,8 +183,10 @@ WritableBase.prototype.end = function(chunk, encoding, cb) {
178183
encoding = null;
179184
}
180185

181-
if (chunk !== null && chunk !== undefined)
186+
if (chunk !== null && chunk !== undefined) {
187+
// TODO (ronag): Propagate callback error.
182188
this.write(chunk, encoding);
189+
}
183190

184191
// This is forgiving in terms of unnecessary calls to end() and can hide
185192
// logic errors. However, usually such errors are harmless and causing a
@@ -191,7 +198,7 @@ WritableBase.prototype.end = function(chunk, encoding, cb) {
191198
let called = false;
192199
this[kFlush](state, (err) => {
193200
if (called) {
194-
// TODO(ronag): ERR_MULTIPLE_CALLBACK?
201+
errorOrDestroy(this, new ERR_MULTIPLE_CALLBACK());
195202
return;
196203
}
197204
called = true;
@@ -225,7 +232,7 @@ WritableBase.prototype.end = function(chunk, encoding, cb) {
225232
function finish(stream, state) {
226233
// TODO(ronag): state.closed, state.errored, state.destroyed?
227234

228-
if (state.errorEmitted)
235+
if (state.errorEmitted || state.closeEmitted)
229236
return;
230237

231238
// TODO(ronag): This could occur after 'close' is emitted.
@@ -329,5 +336,7 @@ ObjectDefineProperties(WritableBase.prototype, {
329336
});
330337

331338
module.exports = {
332-
WritableBase
339+
WritableBase,
340+
WritableStateBase,
341+
errorOrDestroy
333342
};

test/parallel/test-stream-writable-write-error.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function test(autoDestroy) {
3131
{
3232
const w = new Writable({
3333
autoDestroy,
34-
_write() {}
34+
write() {}
3535
});
3636
w.end();
3737
expectError(w, ['asd'], 'ERR_STREAM_WRITE_AFTER_END');
@@ -40,23 +40,23 @@ function test(autoDestroy) {
4040
{
4141
const w = new Writable({
4242
autoDestroy,
43-
_write() {}
43+
write() {}
4444
});
4545
w.destroy();
4646
}
4747

4848
{
4949
const w = new Writable({
5050
autoDestroy,
51-
_write() {}
51+
write() {}
5252
});
5353
expectError(w, [null], 'ERR_STREAM_NULL_VALUES', true);
5454
}
5555

5656
{
5757
const w = new Writable({
5858
autoDestroy,
59-
_write() {}
59+
write() {}
6060
});
6161
expectError(w, [{}], 'ERR_INVALID_ARG_TYPE', true);
6262
}
@@ -65,7 +65,7 @@ function test(autoDestroy) {
6565
const w = new Writable({
6666
decodeStrings: false,
6767
autoDestroy,
68-
_write() {}
68+
write() {}
6969
});
7070
expectError(w, ['asd', 'noencoding'], 'ERR_UNKNOWN_ENCODING', true);
7171
}

0 commit comments

Comments
 (0)