bloom-lang / bud

Prototype Bud runtime (Bloom Under Development)
http://bloom-lang.net
Other
854 stars 60 forks source link

Exceptions should not be silently ignored #311

Closed JoshRosen closed 11 years ago

JoshRosen commented 11 years ago

It looks like Bud doesn't log all exceptions that occur while evaluating rules. This can make certain types of bugs difficult to track down.

As an example, consider this program:

require 'rubygems'
require 'bud'

class MyMod
  include Bud

  state do
    table :tab, []
  end

  bootstrap do
    tab <= [[nil]]
  end

  bloom do
    stdio <~ tab {|x| x[0][0] }
    stdio <~ [["Hello"]]
  end

end

a = MyMod.new
a.start
a.tick

This program contains a bug, since it attempt to call the [] method on a nil object. I expect this program to print "Hello". Instead, it silently fails with no feedback. "Hello" isn't printed because the exception seems to stop other rules from being evaluated during that tick.

The silent failure appears to be caused by tick_internal swallowing exceptions in an ensure block. This fix adds logging for those exceptions, but I'm not sure if this is the right approach:

diff --git a/lib/bud.rb b/lib/bud.rb
index 5eb3058..5fc5b8f 100644
--- a/lib/bud.rb
+++ b/lib/bud.rb
@@ -1151,6 +1151,8 @@ module Bud
       @inbound.clear
       @reset_list.each {|e| e.invalidated = false; e.rescan = false}

+    rescue Exception => ex
+      puts ex.message, ex.backtrace
     ensure
       @inside_tick = false
       @tick_clock_time = nil
neilconway commented 11 years ago

When I run the provided test case, I don't get a silently failure:

(eval):1:in `block in eval_rule': undefined method `[]' for nil:NilClass (NoMethodError)
    from /Users/neilc/.rvm/gems/ruby-1.9.3-p392/gems/bud-0.9.7/lib/bud/executor/elements.rb:121:in `call'
    from /Users/neilc/.rvm/gems/ruby-1.9.3-p392/gems/bud-0.9.7/lib/bud/executor/elements.rb:121:in `push_out'
    from /Users/neilc/.rvm/gems/ruby-1.9.3-p392/gems/bud-0.9.7/lib/bud/executor/elements.rb:105:in `insert'
    from /Users/neilc/.rvm/gems/ruby-1.9.3-p392/gems/bud-0.9.7/lib/bud/executor/elements.rb:127:in `block in push_out'
[...]

This is with the latest code from master and Ruby 1.9.3-p392. Can you double-check that the provided test case repros the problem for you?

BTW, ensure doesn't (shouldn't?) swallow exceptions.

JoshRosen commented 11 years ago

Reinstalling Bud seems to have fixed the test case, so I'll close this issue.

My issue was motivated by a problem that I ran into in a program where I was calling tick in a background thread, so the exception was being thrown in that thread but only reported once thread.join was called on the thread. A timeout in my program prevented that thread's join method from being called, which prevented the traceback from being printed and masked the bug.

neilconway commented 11 years ago

Ah, gotcha. Well, if you run across a situation where we're silently swallowing exceptions, please re-file.