Rerunning After an Exception


Problem

You want to rerun some code that raised an exception, having (hopefully) fixed the problem that caused it in the first place.

Solution

Retry the code that failed by executing a retry statement within a rescue clause of a code block. retry reruns the block from the beginning.

Here’s a demonstration of the retry statement. The first time the code block runs, it raises an exception. The exception is rescued, the problem is “fixed,” and the code runs to completion the second time:

	def rescue_and_retry
	  error_fixed = false
	  begin
	    puts 'I am before the raise in the begin block.'
	    raise 'An error has occurred!' unless error_fixed
	    puts 'I am after the raise in the begin block.'
	  rescue
	    puts 'An exception was thrown! 
Retrying…’
		error_fixed = true
		retry
	  end
	  puts ‘I am after the begin block.’
	end
	rescue_and_retry
	# I am before the raise in the begin block.
	# An exception was thrown! 
Retrying…
	# I am before the raise in the begin block.
	# I am after the raise in the begin block.
	# I am after the begin block.

Discussion

Here’s a method, check_connection, that checks if you are connected to the Internet. It will try to connect to a url up to max_tries times. This method uses a retry clause to retry connecting until it successfully completes a connection, or until it runs out of tries:

	require 'open-uri'

def check_connection(max_tries=2, url='http://www.ruby-lang.org/')
	  tries = 0
	  begin
	    tries += 1
	    puts 'Checking connection…'
	    open(url) { puts 'Connection OK.' }
	  rescue Exception
	    puts 'Connection not OK!'
	    retry unless tries >= max_tries
	  end
	end

	check_connection
	# Checking connection…
	# Connection OK.

	check_connection(2, 'http://this.is.a.fake.url/')
	# Checking connection…
	# Connection not OK!
	# Checking connection…
	# Connection not OK!

Comments

Leave a Reply

You must be logged in to post a comment.