Error handling using aspects in Ruby - ruby

I see myself handling similar exceptions in a rather similar fashion repeatedly and would like to use aspects to keep this error handling code outside of the core business logic. A quick search online pulled up a couple of ruby gems (aquarium, aspector, etc) but I don't see a whole lot of downloads for those gems in rubygems. Given that, I want to believe there are probably other nicer ways to deal with this in Ruby.
get '/products/:id' do
begin
product = find_product params[:id]
rescue Mongoid::Errors::DocumentNotFound
status 404
end
end
get '/users/:id' do
begin
user = find_user params[:id]
rescue Mongoid::Errors::DocumentNotFound
status 404
end
end
In the above example, there are 2 Sinatra routes that look for a requested object by ID in MongoDB and throw a 404 if the object were not to be found. Clearly, the code is repetitive and I am looking to find a Ruby way to make it DRY.

You can see answer in this guide.
You code example:
error Mongoid::Errors::DocumentNotFound do
status 404
end

Related

How prevent chef failure on ruby code?

Sometimes Chef fails on the next code (this code not in block or any resource):
tmp = title.force_encoding("ISO-8859-1").encode("UTF-8")
title = tmp.encode('ISO8859-1').force_encoding('UTF-8')
error that I get:
NoMethodError
undefined method `force_encoding' for nil:NilClass
My question is how best practice to ignore any code error and to continue to run rest recipes, thanks
You didn't show where title comes from so they best I can say is to put your code in a ruby_block resource and use the ignore_failure property. You can also use normal Ruby rescue blocks for imperative code but be aware of how that interacts (or rather, doesn't) with resources, see https://coderanger.net/two-pass/ for some details on the loading process Chef uses.

Rails 4 Ignore Error/Exception and Continue

Sorry if it's an easy question, I am pretty new to Ruby.
When users sign up, or login I would like to keep statistics with Redis
def create
#user = User.new(user_params)
if #user.save
$redis.hincrby("2016MMDD", "new_users", 1)
render json: #user
end
end
If for any reason $redis.hincrby fails, is there a way to continue the execution of the code and render the user anyway?
Sure, just wrap the risky code in a begin/rescue/end block that captures the issue and continues execution.
http://rubylearning.com/satishtalim/ruby_exceptions.html. - see handling exceptions.
You might want to research what exceptions to look for, say if redis has gone away, rather than the base Exception catch

abort in rails loop function

I've got a function in my rails controller (I know, not the rails way, but I find it easier to write in the controller when I have something big like this and then move to the model).
I have an error in a array that I'm looping through, unfortunately, the error is being added somewhere in the loop. It is a big array with lots of properties, and I'm trying to figure out where the error is being caused.
I think I can isolate which object in the array is causing the error, but I can't get it to print.
Aparently ruby has an abort('message') function, but that returns an error in rails.
return render isn't working, it gives me an error that render and/or redirect is being called multiple times. How can I do a php type die in this situation?
This SO Post makes an excellent suggestion.
raise RuntimeError, 'Message goes here'
In the 'Message goes here' section you could even add in the array element:
array.each do |array_element|
<logic>
raise RuntimeError, "#{array_element.inspect}; Message goes here"
end

How to check if a template exists in Sinatra

In the Sinatra ruby framework, I have a route like this:
get '/portfolio/:item' do
haml params[:item].to_sym
end
This works great if the template that exists (e.g., if I hit /portfolio/website, and I have a template called /views/website.haml), but if I try a URL that doesn't have a template, like example.com/portfolio/notemplate, I get this error:
Errno::ENOENT at /portfolio/notemplate
No such file or directory - /.../views/notemplate.haml
How can I test and catch whether the template exists? I can't find an "if template exists" method in the Sinatra documentation.
Not sure if there is a Sinatra specific way to do it, but you could always catch the Errno::ENOENT exception, like so:
get '/portfolio/:item' do
begin
haml params[:item].to_sym
rescue Errno::ENOENT
haml :default
end
end
The first answer is not a good one because if a file does not exist a symbol is created anyway. And since symbols are not garbage collected you're easily leaking memory. Just think of a ddos attack against nonexisitng files that create symbols all the time. Instead use this route here (taken from one of my projects routing css files):
# sass style sheet generation
get '/css/:file.css' do
halt 404 unless File.exist?("views/#{params[:file]}.scss")
time = File.stat("views/#{params[:file]}.scss").ctime
last_modified(time)
scss params[:file].intern
end

Ruby Web API scraping / error handling with Hpricot

I have written a simple ruby gem to scrape a set of websites, providing a simple API, inside the gem itself I have included a retry method... to attempt to use Hpricot 3 or more times on failure mostly due to timeouts.
def retryable(options = {}, &block)
opts = { :tries => 1, :on => Exception }.merge(options)
retry_exception, retries = opts[:on], opts[:tries]
begin
return yield
rescue retry_exception
retry if (retries -= 1) > 0
end
yield
end
So now, in my Rails app which uses this gem i have created I'm wondering how I should handle errors should the Gem itself fail to produce a result, for whatever reason...
models/Available.rb
data = Whatever.find_item_by_id options
unless hwdata
raise "Web error "
end
I'm not quite sure how to handle this... at this point I don't really care about retrying, I only want a return a result, either a hash which the gem returns or returns false with some error?
For normal erros, Like 404, 500 etc, whatever mechanism you are using to fetch the website content, will throw the errors, for other reasons, the Gem should raise the other errors, and informs your rails app, where they can be handled, because its specific to that app.
The Gem should be as generic as possible, for reuse etc.

Resources