class Opal::Nodes::RescueNode

def body_code

def body_code
  body_code = (body.nil? || body.type == :resbody ? s(:nil) : body)
  body_code = compiler.returns(body_code) unless stmt?
  body_code
end

def compile

def compile
  scope.rescue_else_sexp = children[1..-1].detect { |sexp| sexp && sexp.type != :resbody }
  _has_rescue_handlers = false
  if handle_rescue_else_manually?
    line 'var $no_errors = true;'
  end
  closure_type = Closure::NONE
  closure_type |= Closure::JS_FUNCTION if expr? || recv?
  if has_retry?
    closure_type |= Closure::JS_LOOP        \
                 |  Closure::JS_LOOP_INSIDE \
                 |  Closure::RESCUE_RETRIER
  end
  push_closure(closure_type) if closure_type != Closure::NONE
  in_rescue(self) do
    push 'try {'
    indent do
      line stmt(body_code)
    end
    line '} catch ($err) {'
    indent do
      if has_rescue_else?
        line '$no_errors = false;'
      end
      children[1..-1].each_with_index do |child, idx|
        # counting only rescue, ignoring rescue-else statement
        next unless child && child.type == :resbody
        _has_rescue_handlers = true
        push ' else ' unless idx == 0
        line process(child, @level)
      end
      # if no resbodys capture our error, then rethrow
      push ' else { throw $err; }'
    end
    line '}'
    if handle_rescue_else_manually?
      # here we must add 'finally' explicitly
      push 'finally {'
      indent do
        line 'if ($no_errors) { '
        indent do
          line stmt(rescue_else_code)
        end
        line '}'
      end
      push '}'
    end
  end
  pop_closure if closure_type != Closure::NONE
  wrap 'do { ', ' break; } while(1)' if has_retry?
  # Wrap a try{} catch{} into a function
  # when it's an expression
  # or when there's a method call after begin;rescue;end
  if expr? || recv?
    if scope.await_encountered
      wrap '(await (async function() { ', '})())'
    else
      wrap '(function() { ', '})()'
    end
  end
end

def handle_rescue_else_manually?


wrapping current rescue.
Returns true when there's no 'ensure' statement
def handle_rescue_else_manually?
  !in_ensure? && has_rescue_else?
end

def has_retry?

def has_retry?
  @sexp.meta[:has_retry]
end

def rescue_else_code

def rescue_else_code
  rescue_else_code = scope.rescue_else_sexp
  rescue_else_code = compiler.returns(rescue_else_code) unless stmt?
  rescue_else_code
end