Rerunning After an Exception
Credit: Steve Arneil
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.
Heres 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
Heres 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!
See Also
- Recipe 17.2, "Raising an Exception"
- Recipe 17.3, "Handling an Exception"
Категории