Ошибка:

При работе с transform - стримом выводилась ошибка

$ coffee urlsgenerator.coffee|coffee splitter-case.coffee 
/home/space1000/tst/streams/splitter-case.coffee:8
      this.push(chunk.toString());
           ^
TypeError: undefined is not a function
  at [object Object]._onTimeout (/home/space1000/tst/streams/splitter-case.coffee:5:9)
  at Timer.listOnTimeout (timers.js:110:15)

events.js:85
      throw er; // Unhandled 'error' event
            ^
Error: write EPIPE
  at exports._errnoException (util.js:746:11)
  at WriteWrap.afterWrite (net.js:766:14)

Причина:

Ошибка не связана с потоками или стримингом. Ошибка была простой ошибкой, которую выкидывает интерпретатор в процессе работы кода. В данном случае она находится в самом верху:

/home/space1000/tst/streams/splitter-case.coffee:8
      this.push(chunk.toString());
           ^
TypeError: undefined is not a function

Однако, ввиду того, что в stdout уже пайпнут вышеупомянутый трасформ-стрим, обычный вывод ошибок, который в ноде идёт не в stderr, а в stdout (интересно, можно ли это изменить?), да и вообще вывод в stdout чего угодно уже считается тяжким преступлением и карается выбрасыванием Error: write EPIPE, что и придаёт обычной с виду ошибке такую мудацкую нечитаемую форму, которая заставляет пенять на какие-то скрытые баги в коде самой ноды или coffeescript или вообще хуй знает чего.

Пример:

urlsgenerator.coffee

rs = (require 'stream').Readable()
rs.drained = false

outputData = 
[
  "http://ya.ru "
  "http://goo"
  "gle.com\n"
  "http://bing.com "
  "http://y"
  "aho"
  "o.com\n"
  "http://rambler.ru"
]

intervalId = setInterval(
  ->
    if rs.drained
      if outputData.length isnt 0
        rs.drained = false
        #console.error(outputData.shift())
        rs.push(outputData.shift())
      else
        rs.push(null)
        clearInterval(intervalId)
  ,250
)

rs._read = ->
  rs.drained = true

rs.pipe(process.stdout)

splitter-case.coffee

ts = new (require 'stream').Transform()
ts._transform = (chunk, encoding, done) ->
  setTimeout(
    ->
      @.push(chunk.toString())
      done()
    ,1000
  )
 
process.stdin.pipe(ts)
ts.pipe(process.stdout)

Вывод:

$ coffee urlsgenerator.coffee|coffee splitter-case.coffee 
/home/space1000/tst/streams/splitter-case.coffee:8
      this.push(chunk.toString());
           ^
TypeError: undefined is not a function
  at [object Object]._onTimeout (/home/space1000/tst/streams/splitter-case.coffee:5:9)
  at Timer.listOnTimeout (timers.js:110:15)

events.js:85
      throw er; // Unhandled 'error' event
            ^
Error: write EPIPE
  at exports._errnoException (util.js:746:11)
  at WriteWrap.afterWrite (net.js:766:14)

Обновлённый код splitter-case с исправленной (типичной) ошибкой:

ts = new (require 'stream').Transform()
ts._transform = (chunk, encoding, done) ->
  setTimeout(
    =>
      @.push(chunk.toString())
      done()
    ,1000
  )
 
process.stdin.pipe(ts)
ts.pipe(process.stdout)

Результат выполнения той же операции:

$ coffee urlsgenerator.coffee|coffee splitter-case.coffee 
http://ya.ru http://google.com
http://bing.com http://yahoo.com
http://rambler.ru

[ ]