Ruby and Sinatra - ruby

I started writing a simple Sinatra app today and I am trying to understand the error reporting but for some reason I can't get it to work correctly.
I know here, http://railsapi.com/doc/sinatra-v1.0/, it talks about working with error reporting/handling but when I run their examples I can't get it to work.
require 'sinatra'
error 400..510 do
'Boom'
end
get '/say/*' do
params[:splat]
end
When I run the app on my computer I get a 404 error code, but the 'Boom' text does not display in the browser, just the browser 404 page. I am sure I am doing something wrong, but just can't figure it out.

I will wager its your browser. On my MacBook Pro:
Chrome "helpfully" displays a "Oops! This link appears to be broken." page.
Safari displays the expected Boom text.
Firefox displays the expected Boom text.

It seems that Sinatra throws Sinatra::NotFound exception (404) to a specific handler. Simply modify the code as follows,
require 'sinatra'
not_found do
'Boom in NOT_FOUND.'
end
error 400..510 do
'Boom'
end
get '/say/*' do
params[:splat]
end
It works well in Chrome and Firefox on Mac OSX.

Related

How to use ruby to scrape a react website from a remote linux server?

I want to scrape a react website using the ruby watir gem on a remote linux server but keep getting the following error:
/var/lib/gems/2.3.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/firefox/binary.rb:134:in
path': can't modify frozen String (RuntimeError) from
/var/lib/gems/2.3.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/service.rb:45:in
firefox'
Here is my code:
require 'watir'
browser = Watir::Browser.new :firefox, headless: true
browser.goto("https://www.pinterest.com")
There is a similar question here but the links either return 404 or are archived and the code deprecated.
I need to login, then get a new page and push buttons on that page to download a report file for a date range.
You'll get that error if Firefox isn't installed, or isn't accessible on your path. Reinstall if you already have it.
Source: selenium/webdriver/firefox/binary.rb:134:in `path': can't modify frozen String (FrozenError)
So, you might want to use Firecast, a reinstall might help. In case you have a different browser, you could test with Chrome for instance.
Some more things to look at:
You might also need to install the right webdriver. You can also use https://github.com/titusfortner/webdrivers
I have got the same error as you posted, then I ran gem install webdrivers and used it in the code, also I switched to chrome:
require 'watir'
require 'webdrivers'
browser = Watir::Browser.new :chrome, headless: true
browser.goto("https://www.pinterest.com")
Finally, without webdrivers you get something like
C:/tools/ruby26/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/service.rb:136:in `binary_path': Unable to find chromedriver. Please download the server from (Selenium::WebDriver::Error::WebDriverError)
https://chromedriver.storage.googleapis.com/index.html and place it somewhere on your PATH.
More info at https://github.com/SeleniumHQ/selenium/wiki/ChromeDriver.
and with all set up correctly you might get something like (most likely related to Chrome):
DevTools listening on ws://127.0.0.1:57725/devtools/browser/34a42518-c3d9-4e14-af8e-9a137b11625b
[0808/012434.304:INFO:CONSOLE(0)] "The Content-Security-Policy directive 'prefetch-src' is implemented behind a flag which is currently disabled.
", source: https://www.pinterest.com/ (0)
[0808/012437.286:INFO:CONSOLE(240)] "No signed in Google accounts available - visit accounts.google.com to ensure that at least one account is signed in, otherwise no data will be returned from this API.", source: https://www.gstatic.com//mss/boq-identity//js/k=boq-identity.IdentityYoloWebModuleset.en_US.fUFh6X86RzU.es5.O/am=Aw/d=1/rs=AOaEmlH5BdY58S_qoulxSYv6tYMpThlVYw/m=yolo_frame_library (240)

Changes to app.rb don't seem to go into effect

I need to test a GET request in sendRequest.js:
$.get( '/test/test2', {name: 'Larry', time: '2pm'} );
This sends the request fine and everything works on the JavaScript end, but obviously returns a 404 (route not found) so I added in app.rb:
get '/test/test2' do
logger.info "this is a test log"
end
I sent the request again, and I got the same 404.
This scenario originates from none of my changes in app.rb going into effect. I've deleted entire routes, commented stuff out, etc., nothing I do in app.rb seems to have any effect on the server.
Any ideas?
Have you tried stopping and restarting the server?
By default Sinatra won't know its code has changed, and Ruby will have loaded all the script into memory and won't look at the file.
Stopping the server, by using Cntrl+C then restarting the server will refresh Ruby's idea of what should be done.

Can't get custom error pages to work in Padrino

I started to build a website with padrino. At the moment the main class of my app is the simplest thing in the world:
class App < Padrino::Application
enable :sessions
get :index do
send_file 'public/view/index.html'
end
error 404 do
send_file 'public/view/errors/404.html'
end
end
So the views are simply htmls - the idea behind it is to use angularjs to render all the thingies provided by a rest api. I guess that's fairly standard.
My problem is - although it works fine for rendering the home page (localhost:3000/), the custom error doesn't work at all; let's say I try localhost:3000/test - the standard "Sinatra doesn’t know this ditty" page is rendered instead.
I'm running padrino 0.12.4 with WEBrick 1.3.1. What am I doing wrong here?
I believe what's going on here is that when you go to localhost:3000/test, your Sinatra app is looking for the "test" action under your App Controller. Obviously this action is not being found because it's not listed as a route! Therefore explicitly tell Sinatra to return a 404 page if the diddy wasn't found:
error Sinatra::NotFound do
content_type 'text/plain'
[404, 'Not Found']
end

Ruby Watir WebDriver Net::ReadTimeout

I am trying to use Watir to get the source code of Facebook after I authenticate using Watir. It gives this specific error.
/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/protocol.rb:158:in `rescue in rbuf_fill': Net::ReadTimeout (Net::ReadTimeout)
I believe that because there are too many AJAX requests in the homepage, webdriver detects it as the page is not fully loaded. So after I logged in, I did this:
p "starts"
Watir::Wait.until {
browser.div(:'class' => '_586i').exists?
}
p "finishes"
But after it prints "starts" then it gives a timeout error, and doesn't get the source code of the website.
I've been getting this error for some websites quite a lot after I try to, eg, browser.button.click that is redirecting to another page heavily loaded with Ajax. I found this:
browser.execute_script('document.getElementsByTag('button')[0].click()')
sleep 10
with adjusted sleep (or, much better, .wait_until_present) helps.
You can force the browser to wait until all ajax calls has been loaded with
sleep(1) until browser.execute_script("return jQuery.active") == 0

Rendering 404 in sinatra if file not found

I have a basic sinatra app that renders files from a directory. What I'd like is returns 404 if page does not exist. Currently it raise 500 error.
get '/:page' do
erb :"pages/#{params[:page]}", layout: :"layouts/application"
end
Try this ;)
# 404 Error!
not_found do
status 404
erb :oops
end
Make yourself a 404 page with whatever name you like (mine is oops.erb, for example), and this should work just fine.
not_found is Sinatra's error-handling helper for grabbing error 500s and 404 not-founds that it returns. You can then change the HTTP status and corresponding view using it. Check out the documentation for all of Sinatra's error handler's: they're super useful!
You could do something like:
get '/:page' do
requested_erb = File.join(root, 'pages', params[:page])
pass unless File.exists?(requested_erb)
erb :"#{requested_erb}", :layout: :"layouts/application"
end
I haven't tested this, so there might be some issues with the above code, but that's the general idea in my head.

Resources