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.

Nakilon
  • 34,866
  • 14
  • 107
  • 142
Tintin81
  • 9,821
  • 20
  • 85
  • 178

1 Answers1

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.

MrTheWalrus
  • 9,670
  • 2
  • 42
  • 66
  • 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. – nzifnab Jan 09 '14 at 21:15
  • 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. – Tintin81 Jan 09 '14 at 21:18
  • @Tintin81 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) – MrTheWalrus Jan 09 '14 at 21:23