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

FiberIterator breaks normal exception handling #206

Open
dgutov opened this issue Jun 28, 2016 · 3 comments
Open

FiberIterator breaks normal exception handling #206

dgutov opened this issue Jun 28, 2016 · 3 comments

Comments

@dgutov
Copy link
Collaborator

dgutov commented Jun 28, 2016

Example (failing spec):

  it "permits normal handling of errors" do
    caught = nil

    EM.synchrony do
      begin
        EM::Synchrony::FiberIterator.new(0..1, 2).each do |num|
          raise "#{num} here"
        end
      rescue => e
        caught = e.message
      end

      EM.stop
    end

    expect(caught).to eq("0 here")
  end

The rescue block is never entered, and the only way to catch the exception is with EM.error_handler or catching it outside of the EM loop. Neither approach is composable.

@igrigorik Any ideas for an easy fix?

@dgutov
Copy link
Collaborator Author

dgutov commented Jun 28, 2016

Right. But still, this kinda works (it outputs 3 at the end, at least):

    counter = 0

    EM.synchrony do
      f = Fiber.current

      maybe_stop = proc { f.resume if counter == 2 }

      f1 = Fiber.new do
        EM::Synchrony.sleep(1)
        counter += 1
        puts counter
        maybe_stop[]
      end

      f2 = Fiber.new do
        begin
          EM::Synchrony.sleep(1)
          counter += 1
          puts counter
          raise "aaa"
        ensure
          maybe_stop[]
        end
      end

      EM.next_tick { f1.resume }
      EM.next_tick { f2.resume }

      begin
        Fiber.yield
      ensure
        puts 3
      end
      EM.stop
    end

And this catches the error, even though it was raised in a different fiber:

    f = Fiber.new do
      raise "bar"
    end

    begin
      f.resume
    rescue
      puts "safety caught"
    end

Maybe all worker fibers should be created by the caller fiber, on the main thread.

@dgutov
Copy link
Collaborator Author

dgutov commented Jun 28, 2016

Alas, no. The second option doesn't seem like it'll work either when one of the worker fibers is suspended and then woken by the reactor thread (which is how we handle asynchrony normally).

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

No branches or pull requests

2 participants