Reputation: 2984
I'm trying to make my sinatra app show a custom error page when an error is raised on the server (e.g. an IOError or ArgumentError).
Currently I'm using AJAX to load the results into a certain #results
div, but if and when an error arises on the server, I would like an error page to open up on a new page.
Currently, the IOError is shown on the server and a error is seen in the console (the server responded with a status of 500 (Internal Server Error)). Other than that, nothing happens.
I think that I have to play about with the Javascript (as well as the Sinatra::Base class) but I've spent the whole of yesterday and this morning not getting anywhere.
I would be very grateful for any help. I've created an oversimplified version of my app which I have shown below...
Sinatra_app.rb
require 'sinatra/base'
require9 'sinatra'
require 'slim'
# A helper module
module GVhelpers
def create_results(name)
# raise IOError, "There's a problem..."
return "<p>The Server Says 'Hey #{name}'</p>"
end
end
class GVapp < Sinatra::Base
helpers GVhelpers
set :root, File.dirname(__FILE__)
error do
@error = env['sinatra.error']
slim :"500", :locals => {:error => error}
end
get '/' do
slim :index
end
post '/form' do
name = params[:personName]
create_results(name)
end
end
GVapp.run!
index.slim (in views folder)
script src="/jquery.min.js"
script src="/Gvapp.js"
form#sayHey action="/form" method="post"
| Name:
input type="text" name="personName"
br
input type="submit"
#output
500.slim (in views folder)
h1 Oops! Something went Wonky!
p Apologies, there was an error with your request:
strong request.env['sinatra.error'].message
p If the error persists, please contact the administrator.
Gvapp.js (in public folder)
$(document).ready(function() {
$('#sayHey').submit(function(e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '/form',
data: $('#sayHey').serialize(),
success: function(response){
$('#output').html(response);
}
})
})
})
Upvotes: 3
Views: 5254
Reputation:
Sinatra swallows exceptions when run in the development
environment by default and shows its debugging error page instead. So, to trigger your custom error handlers, you have to either run the application inside a Rack environment other than development
(probably production
), or preferably, tell Sinatra to not use its default error handlers in development
mode.
Consider the following, standalone Sinatra application example:
require "sinatra"
#disable :show_exceptions
get "/" do
raise RuntimeError.new("boom")
end
error RuntimeError do
"A RuntimeError occured"
end
If you run this application using the default development
environment like this:
$ ruby foo.rb
Then you will get Sinatra’s default error page. If you uncomment the disable
line in the example, the error
handler will be triggered instead, displaying a page containing "A RuntimeError occured". Alternatively, you can, as explained, run the application in an environment other than development
as only that one pre-sets the show_exception
setting. You can do that by setting the RACK_ENV
environment variable:
$ RACK_ENV=production ruby foo.rb
For development purposes, setting RACK_ENV
to production
is not the correct way of course. Use disable :show_exceptions
instead. You can use a configure
block as outlined in the Sinatra README to conditionally disable the setting for the development
environment.
configure :development do
disable :show_exceptions
end
That behaviour is documented in Sinatra’s documentation on configuration, along with several other useful settings.
Upvotes: 9