Return false vs raising an exception in Ruby- When and why?
exception, ruby, ruby-on-rails
Solution
Once upon a time there was a language with no exception constructs (c). Each message returned an integer - 0 for success or some error-code for failure. If the caller did not check the return code before continuing - he'd be screwed. Also, most of the time the caller had nothing he could do about the failure, so even when he did check the result - the only intelligent thing he could do is return its own error code...
Then came c++, with exception constructs, just for these use-cases. Exceptions are made for times where the method got into a situation it could not handle (like reading a file that was not there, or surfing the web without internet connection).
Abusing the Exception construct means that an exception is raised in a totally expected situation, for example:
def even?
if (self % 2 != 0)
raise NumberNotEvenException
end
end
Here a number being odd is legitimate, and expected; throwing an error is misusing the exception construct.
Throw an exception when the method cannot fulfill what it promised to do.
On the flip side - returning `nil` or `false` when a method fails brings us back to the happy c days, where it is the burden of the caller to notice the failure, and figure out what went wrong - not fun.
Problem
I am really confused on the concepts of: - Don't use exceptions as control flow - Don't return nil/false as an exception Say I have the following instance method: ``` class Logo # This method has some logic to create an image using Rmagick def process begin @logo_image = RmagickHelper.new(self.src) rescue Magick::ImageMagickError raise Exceptions::LogoUnprocessable, "ImageMagick can't process the URL" end end end ``` So in a more general method I have the following: ``` def build_all_images begin @logo.process rescue Exceptions::LogoUnprocessable @logo.status = 'unprocessable' return false #This terminates the method so no more stuff is processed, because logo could not be processed. end #.... end ``` My question is: Is this correct to do: ``` raise Exceptions::LogoUnprocessable, "ImageMagick can't process the URL" ``` Or should I have just done ``` return false ```