Sinatra before filter - ruby-on-rails

I'm on Sinatra and i don't understand how to deal with my problem:
I want to "send" to curl a custom message when he try to go on a wrong path.
curl http://localhost:port/blabla
It's an error 404 but i want to send him thing like 'error try other path'
I tried with this :
before'/*' do
if (params[:splat].to_s =~ /path_i_want/) != 2
'wrong path'
end
end
or with raise 404 but it doesn't work.
Could you help me please ?
Regards.

Sinatra has a built-in handler for 404, see Error Handling page. You could do all your logic in there.
Not Found
When a Sinatra::NotFound exception is raised, or the
response’s status code is 404, the not_found handler is invoked:
not_found do
'This is nowhere to be found.'
end

Related

How to catch a 500 Internal Server Error in Rails

I have done this tons of times before when fetching things from a database, etc.
For my specific case I am using a 3rd party to connect to a piece of hardware... Anyways, in the case of an error, such as an invalid id obviously, we want to raise a exception or a rescue... but unfortunately I don't know how to raise it because by the time it is hit, it's too late (I think)
Here...
#
# getting params and saving item above...
#
if item.save
device = RubySpark::Device.new("FAKEUNITID800")
device.function("req", "ITEM")
redirect_to controller: 'items', action: 'edit_items'
end
If this was a valid ID, everything would work, and it would take you to the /edit page! But the issue is, with an invalid ID, it just does...
Completed 500 Internal Server Error in 897ms
RubySpark::Device::ApiError - Permission Denied: Invalid Device ID:
I checked out the following tutorials
Rescue StandardError, Not Exception
How to catch 404 and 500 error in Rails?
Dynamic Rails Error Pages
But honestly, they just make me more confused. Maybe I have the wrong approach to this. I always thought that first you make the request, and then you have a fall back case, depending what status (ie. 200, 500, 404) you get... you go from there.
Rails returns an 500 Internal Server Error response because an exception was raised that it does not no how to handle. You can't rescue "500 Internal Server Error" in Rails because it is not an exception - its the framework bailing from an uncaught exception to avoid data loss or unpredictable behavior.
Fortunatly you don't have to. You can just rescue the RubySpark exception:
begin
device = RubySpark::Device.new("FAKEUNITID800")
device.function("req", "ITEM")
rescue RubySpark::Device::ApiError => e
logger.error(e.message)
end
You can also use rescue_from in Rails controllers that wraps the entire action in a before block:
class FooController < ApplicationCotnroller
rescue_from RubySpark::Device::ApiError, with: :do_something
# ...
end

How to handle httparty errors rails

I am using some api with httparty gem
I have read this question:
How can I handle errors with HTTParty?
And there are two most upvoted answers how to handle errors
first one using response codes (which does not address connection failures)
response = HTTParty.get('http://twitter.com/statuses/public_timeline.json')
case response.code
when 200
puts "All good!"
when 404
puts "O noes not found!"
when 500...600
puts "ZOMG ERROR #{response.code}"
end
And the second - catching errors.
begin
HTTParty.get('http://google.com')
rescue HTTParty::Error
# don´t do anything / whatever
rescue StandardError
# rescue instances of StandardError,
# i.e. Timeout::Error, SocketError etc
end
So what is the best practice do handle errors?
Do I need to handle connection failures?
Right now I am thinking of combining this two approaches like this:
begin
response = HTTParty.get(url)
case response.code
when 200
# do something
when 404
# show error
end
rescue HTTParty::Error => error
puts error.inspect
rescue => error
puts error.inspect
end
end
Is it a good approach to handle both connection error and response codes?
Or I am being to overcautious?
You definitely want to handle connection errors are they are exceptions outside the normal flow of your code, hence the name exceptions. These exceptions happen when connections timeout, connections are unreachable, etc, and handling them ensures your code is resilient to these types of failures.
As far as response codes, I would highly suggest you handle edge cases, or error response codes, so that your code is aware when there are things such as pages not found or bad requests which don't trigger exceptions.
In any case, it really depends on the code that you're writing and at this point is a matter of opinion but in my opinion and personal coding preference, handling both exceptions and error codes is not being overcautious but rather preventing future failures.

RoR JSON.parse catching an error

Writing an app that reaches out to an api (ETSY) and brings back some JSON but sometimes I get a 403 error and if I get an error I want to show an error page but I'm not sure how to check for that error and do something else.
my_hash = JSON.parse(open("https://openapi.etsy.com/v2/listings/#{$productId}?api_key=XXXX&fields=title,url,price,description&includes=MainImage").read)
I've looked around for a while but haven't seen what I'm looking for.
You can use a begin rescue block to redirect the user whenever you hit a 403 error
def index
begin
my_hash = JSON.parse(open("https://openapi.etsy.com/v2/listings/#{$productId}api_key=XXXX&fields=title,url,price,description&includes=MainImage").read)
rescue
redirect_to error_path
end
This is sort of quick and dirty, but I beileve it can get the job done.
This article may also help. http://www.mattjohnston.co/blog/2013/10/18/responding-with-errors-in-rails/
I think you need to check your api response, if the response is 404 then render error page. May be something like this. To getting response from api, you need to use third party like (restclient or httpparty).
def index
response = RestClient get "https://openapi.etsy.com/v2/listings/#{$productId}api_key=XXXX&fields=title,url,price,description&includes=MainImage"
unless response.code == 404
result_hash = JSON.parse(response.body)
// do something
else
// redirect to error page here
end
end
For reference, pls read restclient documentation here.

Why rescue an exception and then raise one?

I'm looking at the mandrill docs for a ruby api call https://mandrillapp.com/api/docs/users.ruby.html#method=ping and I noticed that they rescue Mandrill::Error and then raise another exception.
I'm curious why anyone would ever catch one exception and then raise another one. It doesn't make sense to me.
begin
mandrill = Mandrill::API.new 'YOUR_API_KEY'
result = mandrill.users.ping
# {"PING"=>"PONG!"}
rescue Mandrill::Error => e
# Mandrill errors are thrown as exceptions
puts "A mandrill error occurred: #{e.class} - #{e.message}"
# A mandrill error occurred: Mandrill::InvalidKeyError - Invalid API key
raise
end
rescue Mandrill::Error => e
# Mandrill errors are thrown as exceptions
puts "A mandrill error occurred: #{e.class} - #{e.message}"
# A mandrill error occurred: Mandrill::InvalidKeyError - Invalid API key
raise
end
In this case the same exception is being "re-raised". The only reason for this rescue block is to log specific information about the exception.
begin/rescue blocks are usually used this way when an exception is of special interest and so the authors wanted the exception info to be printed/logged. This is especially the case when the next rescue block is not printing any exception information and instead silently handling it.
raise will throws a runtime exception instead of a normal exception.
Another reason for doing it could be that code wanted to throw a runtime error instead of a normal error. Maybe relevant if the code is in the context of a controller.
However, I think the main reason will be Martin's logging answer.

How can I handle errors with HTTParty?

I'm working on a Rails application using HTTParty to make HTTP requests. How can I handle HTTP errors with HTTParty? Specifically, I need to catch HTTP 502 & 503 and other errors like connection refused and timeout errors.
An instance of HTTParty::Response has a code attribute which contains the status code of the HTTP response. It's given as an integer. So, something like this:
response = HTTParty.get('http://twitter.com/statuses/public_timeline.json')
case response.code
when 200
puts "All good!"
when 404
puts "O noes not found!"
when 500...600
puts "ZOMG ERROR #{response.code}"
end
This answer addresses connection failures. If a URL isn´t found the status code won´t help you. Rescue it like this:
begin
HTTParty.get('http://google.com')
rescue HTTParty::Error
# don´t do anything / whatever
rescue StandardError
# rescue instances of StandardError,
# i.e. Timeout::Error, SocketError etc
end
For more information see: this github issue
You can also use such handy predicate methods as ok? or bad_gateway? like this:
response = HTTParty.post(uri, options)
p response.success?
The full list of all the possible responses can be found under Rack::Utils::HTTP_STATUS_CODES constant.

Resources