How to break out of begin block in Ruby?
Asked Answered
E

1

5

How can I break out of the begin block and jump to the rescue block?

def function
  begin
    @document = Document.find_by(:token => params[:id])
    next if @document.sent_at < 3.days.ago # how can I skip to the rescue block here?
    @document.mark_as_viewed
  rescue
    flash[:error] = "Document has expired."
    redirect_to root_path
  end
end

My attempt using next doesn't work.

Edwinedwina answered 9/1, 2014 at 21:8 Comment(3)
I don't think you're using rescue correctly...Custom
One quick thing if you do this a lot... try using def...rescue...end as opposed to def...begin...rescue...end...endStoddart
@Stoddart 's comment is really helpfulDebbee
B
8

Well, you could raise an error. That's how begin/rescue blocks work. It's not a good idea, though - using error handling for business logic is generally frowned upon.

It seems as though it would make much more sense to refactor as a simple conditional. Something like:

def function
  @document = Invoice.find_by(:token => params[:id])
  if @document.sent_at < 3.days.ago
    flash[:error] = "Document has expired."
    redirect_to root_path
  else
    @document.mark_as_viewed 
  end
end

It seems as though you've confused a few different kinds of block-related keywords here:

Error handling (begin/rescue/end) is for cases where you think something you try might raise an error, and respond in a particular way to it.

next is for iteration - when you're looping through a collection and want to skip to the next element.

Conditionals (if, unless, else, etc.) are the usual way for checking the state of something and executing different bits of code depending on it.

Broom answered 9/1, 2014 at 21:14 Comment(3)
I was going to make an answer that did exactly this. I'll just upvote you. This is the correct way to do it, don't use rescue for simple business logic if nothing exceptional is happening.Custom
Thanks but it's possible to get a nil error for @document that way, isn't it? That was the reason I used the begin/rescue block.Edwinedwina
@Edwinedwina The API says that .find_by is equivalent to .where, so if there's no matching record, it should simply set @document to nil, which you could then check for in order to respond correctly (probably with a status 404? depends on your logic)Broom

© 2022 - 2024 — McMap. All rights reserved.