Last active
December 21, 2015 19:19
-
-
Save miwest929/6353175 to your computer and use it in GitHub Desktop.
Code examples from my Ruby Exception Handling presentation:
http://slid.es/mwest-mdsol/being-exceptional-at-ruby
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Code for Exception Anti-Pattern #1: blah rescue nil | |
| require 'time' | |
| class DoSomeWork | |
| # Bad: Fatal exceptions are swallowed up. | |
| def self.milliseconds(ms) | |
| Time.now.iso8601(ms) rescue nil | |
| end | |
| # Good: Specific about which exception we care about | |
| def self.milliseconds(ms) | |
| Time.now.iso8601(ms) | |
| rescue ArgumentError => e | |
| nil | |
| end | |
| end | |
| puts DoSomeWork.milliseconds(3) | |
| puts DoSomeWork.milliseconds('a') | |
| #------------------------------------------------------------------------------------------------- | |
| # Code for Ruby Exception Idioms | |
| def lazy_job_processor(job) | |
| # Sometimes I just don't feel like doing anything | |
| raise StandardError, "I just don't feel like doing anything" | |
| true | |
| end | |
| def raise_with_ensure(queue) | |
| queue.each {|job| lazy_job_processor(job) } | |
| rescue StandardError => e | |
| puts "Error: #{e.message}! Abort job processing" | |
| else | |
| puts "ELSE: Cool! Actually got my function to do something for once." | |
| ensure | |
| puts "ENSURE: Removing job locks so we're not in an inconsistent state" | |
| end | |
| raise_with_ensure([3,6,7,2,9,11,90]) | |
| #--------------------------------------------------------------------------- | |
| # Code example for Ruby exception retry | |
| # Meet Clippy (infamous from Microsoft Word). I borrowed from the Looney bin. He is in complete denial | |
| # that dividing by zero would raise an exception! | |
| class Sanity | |
| MAX_RETRY = 3 | |
| # Bad | |
| def self.always_retry | |
| 1 / 0 | |
| rescue StandardError => e | |
| puts "That's odd I can't divide by zero. Let me try again!" | |
| retry | |
| end | |
| # Better | |
| def self.max_retry | |
| retry_count = 0 | |
| begin | |
| 1 / 0 | |
| rescue StandardError => e | |
| retry_count += 1 | |
| puts "Attempt #{retry_count}: Can't divide by zero let's try again" | |
| if retry_count >= MAX_RETRY | |
| puts "Well I guess I really can't divide by zero. News to me!" | |
| else | |
| retry | |
| end | |
| end | |
| end | |
| end | |
| # Best | |
| def try_with_retry(max_retry) | |
| retry_count = 0 | |
| begin | |
| yield | |
| rescue StandardError => e | |
| retry_count += 1 | |
| puts "Attempt #{retry_count} failed!" | |
| if retry_count >= max_retry | |
| puts "Reached max number of retries giving up!" | |
| else | |
| retry | |
| end | |
| end | |
| end | |
| Sanity.always_retry | |
| ##Sanity.max_retry | |
| #try_with_retry(3) { 1 / 0 } | |
| # Best to just use existing gem |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment