Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override Sinatra default NotFound error page

Tags:

ruby

sinatra

Is there a way to override the sinatra default NotFound error page ("Sinatra doesnt know this ditty")? I want sinatra to show only a plain string as "Method not found" when it does not found the proper route, but when I raise an 404 error from inside a route I want it to show the passed-in error message.

Implementing the not_found block like this:

 not_found do
    'Method not found.' 
  end

works, but its not a valid option since I want to be able to throw my own NotFound error messages from routes like this:

 get '/' do
    begin
      # some processing that can raise an exception if resource not found
    rescue => e
      error 404, e.message.to_json
    end
  end

But as expected not_found block overrides my error message.

like image 792
João Pereira Avatar asked Dec 09 '11 22:12

João Pereira


3 Answers

If you don't use error handling in your route, you can utilize the built in error route like this (taken and modified from the Sinatra: Up and Running book)

require 'sinatra'

configure do
  set :show_exceptions, false
end

get '/div_by_zero' do
  0 / 0
  "You won't see me."
end

not_found do
  request.path
end

error do
  "Error is: " + params['captures'].first.inspect
end

There is a parameter captures that holds your error. You can access it via params['captures']. It is an array, and in my tests it would contain a single element, which was the error itself (not a string).

Here is information on the request object.

like image 91
Paul Hoffer Avatar answered Nov 12 '22 07:11

Paul Hoffer


Perhaps a more graceful solution than that proposed in the accepted answer is to rescue only Sinatra::NotFound, rather than using the error(404) or not_found styles.

error Sinatra::NotFound do
  content_type 'text/plain'
  [404, 'Not Found']
end

This prevents the "sinatra doesn't know this ditty" default page for routes that you haven't defined, but doesn't get in the way of explicit return [404, 'Something else']-style responses.

like image 37
aocole Avatar answered Nov 12 '22 08:11

aocole


Nevermind, found that all routes are matched in order, so after all routes I put get/post/put/delete '*' do ; end and that solves my problem.

like image 1
João Pereira Avatar answered Nov 12 '22 08:11

João Pereira