Reputation: 18279
In languages that have goto, I like to create an error block at the end of a function (after return) and then when I do error checking within the function, I can just be concise and goto the error handler within each check. As I understand it, this is the one valid use of goto that isn't considered bad practice.
Example in pseudocode:
def example
if (x) goto error
do something
if (y) goto error
do something
If (z) goto error
do something
return
label 'error'
log "error occurred"
begin
redirect_to :back
rescue
redirect_to root_url
end
return;
end
As you can see, in this case, my error block is as long as the function itself, and repeating it 3 times would double the size of my code, and not be very DRY. However, it seems that Ruby doesn't support goto, or at least if it does, as best as I can tell from looking on Google, it's some sort of possibly joke library labeled evil.
Therefore, what are people doing in Ruby in order to handle repeated error checking where the same result should occur in each error?
Upvotes: 2
Views: 688
Reputation: 26979
Here's a little secret: Exceptions are basically glorified gotos. Also, ruby has a catch/throw syntax, see: http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_exceptions.html
In your case, ask, is it really an error or just an undesirable condition. An error to me is when a belongs_to references a record that doesn't exist, but having an empty belongs_to isn't. This changes from situation to situation.
Looking at your comment above, I think I would be more inclined to add some private methods that set the instance variables and return true of false, and chain them together:
if load_model1 && load_model2 && load_model3 ... do regular page view else #render error page, use @load_error end private def load_model1 @model1 = .... if @model1.blank? # or nil? or whatever error condition @load_error="model 1 failed return false else return true end end def load_model2 ... end def load_model3 ... end
Upvotes: 1
Reputation: 56759
You should transfer many of these errors into your models, using Callbacks. These apply to errors that are relevant to actions that involve records in your database, i.e. checking whether a data input is appropriate.
Use before_filters and after_filters to check for errors, especially when you need to perform these checks on multiple controller actions. An example:
before_filter :check_errors
def example
regular code...
end
private
def check_errors
error checking...
end
Use Case statements to improve your if
statements, particularly when you have multiple checks involved.
Use callbacks in your models whenever you can and definitely whenever data saving/updating/validation is involved.
Use before_filters
whenever the code is to be reused across multiple actions (and in my opinion, always whenever you have involved error checking like this).
If you need these checks to occur only once, in this controller action alone, that do not involve records being changed, simply rewrite your code in a valid case statement (but my recommendation would still be to transfer to a before_filter).
Upvotes: 5