dominictarr / through

simple way to create a ReadableWritable stream that works
Other
669 stars 64 forks source link

swallows errors in browser #28

Closed davidguttman closed 9 years ago

davidguttman commented 9 years ago

http://requirebin.com/?gist=775f71b638503eb17820

var hq = require('hyperquest')
var es = require('event-stream')

var tr = es.through(function(data){
  console.log('about to error')
  throw new Error('but it never happens')
  this.queue(data)
})

var rs = hq('http://requirebin.com').pipe(tr)
davidguttman commented 9 years ago

Nevermind, looks like it happens with through2 as well.

http://requirebin.com/?gist=0340a5ff7ed37638c608

dominictarr commented 9 years ago

hmm, what does emitter.emit('error', err) do in the browser if there is no error listener?

davidguttman commented 9 years ago

Throws an Uncaught Error: http://requirebin.com/?gist=30d66aad6bb932df9584

davidguttman commented 9 years ago

I was able to work around this issue in my app by using asap to make the writes async. (I was having a problem with errors happening somewhere after doSomethingWithData and not being able to see them):

var asap = require('asap')
var hq = require('hyperquest')
var es = require('event-stream')
var JSONStream = require('JSONStream')

var stream = urlStream('http://reqr.es/api/users?page=2')
stream.on('data', doSomethingWithData)

function urlStream (url) {
  var stream = es.through(function(data) {this.queue(data) })
  rs = hq(url).pipe(JSONStream.parse('data.*'))
  rs.on('data', function(data) { asap(function() { stream.write(data) }) })
  rs.on('end', function() {stream.end()})
  rs.on('error', function(err) {stream.emit('error', err)})
  return stream
}
dominictarr commented 9 years ago

do you see errors in the dev console? you should be seeing errors being logged there?

davidguttman commented 9 years ago

That was the problem, before using the workaround, errors wouldn't show up in the dev console.

This all started when I was building an app with mercury and at a certain point the app would stop and the page would stay blank. There was nothing in the console and there was much confusion.

Turns out, I was trying to create a struct with a key called "name" which was conflicting with prototype. mercury was throwing an error telling me about this, but it was getting swallowed. All synchronous code that was a result from the .on('data', fn) handler would have errors swallowed if thrown.

If you look in the dev console you can see the issue/workaround here: http://requirebin.com/?gist=c8216144dddf64b286fa

var hq = require('hyperquest')
var es = require('event-stream')
var asap = require('asap')

var tr1 = es.through(function(data){
  console.log('about to error silently')
  throw new Error('never shows in console')
  this.queue(data)
})

var tr2 = es.through(function(data){
  asap(function() {
    console.log('about to error for real')
    throw new Error('but this *does* show in console')
    this.queue(data)
    })
})

var rs1 = hq('http://requirebin.com').pipe(tr1)
var rs2 = hq('http://requirebin.com').pipe(tr2)
dominictarr commented 9 years ago

through doesn't do anything with try-catch, so if thrown errors are being silenced, it's not because of through. some other module must be causing this problem. it's probably whoever called stream.write

I don't see anything in hyperquest. I adjusted your gist to show the stack http://requirebin.com/?gist=c8216144dddf64b286fa

but I can't see a try-catch that it's inside of...