def handle_on_error(msg, error)

      return false if h.state == 'failing'

      err = deflate(error)
      oe_parent = lookup_on_error(err)

      return false unless oe_parent
        # no parent with on_error attribute found

      handler = oe_parent.local_on_error(err)

      return false if handler.to_s == ''
        # empty on_error handler nullifies ancestor's on_error

      workitem = msg['workitem']
      workitem['fields']['__error__'] = err

      immediate =
        if handler.is_a?(String)
          !! handler.match(/^!/)
        elsif handler.is_a?(Array)
          !! handler.first.to_s.match(/^!/)
        else
          false
        end

      # NOTE: why not pass the handler in the msg?
      #       no, because of HandlerEntry (not JSON serializable)

      @context.storage.put_msg(
        'fail',
        'fei' => oe_parent.h.fei,
        'workitem' => workitem,
        'immediate' => immediate)

      true # yes, error is being handled.
    end
def handle_on_error(msg, error)

      return false if h.state == 'failing'

      err = deflate(error)
      oe_parent = lookup_on_error(err)

      return false unless oe_parent
        # no parent with on_error attribute found

      handler = oe_parent.local_on_error(err)

      return false if handler.to_s == ''
        # empty on_error handler nullifies ancestor's on_error

      workitem = msg['workitem']
      workitem['fields']['__error__'] = err

      immediate =
        if handler.is_a?(String)
          !! handler.match(/^!/)
        elsif handler.is_a?(Array)
          !! handler.first.to_s.match(/^!/)
        else
          false
        end

      # NOTE: why not pass the handler in the msg?
      #       no, because of HandlerEntry (not JSON serializable)

      @context.storage.put_msg(
        'fail',
        'fei' => oe_parent.h.fei,
        'workitem' => workitem,
        'immediate' => immediate)

      true # yes, error is being handled.
    end
Looks up parent with on_error attribute and triggers it