rails 4: custom error pages for 404, 500 and where is the default 500 error message coming from?

后端 未结 4 1875
悲&欢浪女
悲&欢浪女 2020-11-27 13:35

Currently in production im getting this text:

500 Internal Server Error
If you are the administrator of this website, then please read this web application\'         


        
相关标签:
4条回答
  • 2020-11-27 13:54

    Here is latest and quick fix for showing custom 404_error page.

    • Add below lines in development.rb or production.rb as per your env.

    config.exceptions_app = self.routes

    config.consider_all_requests_local = false

    • Remove all rm public/{404,500,422}.html
    • Create 404.html.erb file in static folder of your rails project. You can add your custom html here.(this will be using your application layout so don't bother about header and footer content)
    0 讨论(0)
  • 2020-11-27 14:02

    0 讨论(0)
  • 2020-11-27 14:08

    The Error you are experiencing is being thrown from

    https://github.com/rails/rails/blob/4-0-stable/actionpack/lib/action_dispatch/middleware/show_exceptions.rb#L18-L22

    This means, the code your exceptions are getting rescued by are themselves throwing exceptions. You can check your logs for text:

    Error during failsafe response:

    to identify what the exceptions really are originating from and thus solve your problem.

    0 讨论(0)
  • 2020-11-27 14:08

    Error pages in application should be as simple as it possible. Same recommendation concerns their rendering. If your application returns 500 HTTP response code it means that things got wrong already. And there is a chance you could not render error page and display it to user.

    Ideally error pages should be a plain HTML served directly by your web server without hitting application server.

    Speaking of Rails implementation of this idea. It based on using asset pipeline for precompiling the HTML static pages.

    Firstly add new assets type (Rails > 4.1):

    # config/initializers/assets.rb
    
    Rails.application.config.assets.precompile += %w(404.html 500.html)
    Rails.application.config.assets.paths << Rails.root.join('app/assets/html')
    Rails.application.config.assets.register_mime_type('text/html', '.html')
    

    If templating engine is using (e.g. slim, haml), register it via initializer:

    # for Slim
    Rails.application.assets.register_engine('.slim', Slim::Template)
    # for Haml
    Rails.application.assets.register_engine('.haml', Tilt::HamlTemplate)
    

    Now you ready to create pretty error pages in app/assets/html directory using your favorite template engine and Rails built-in view helpers.

    Tips for production

    On production asset pipeline adds digest to compiled assets and stores files under default folder (typically shared/public/assets on production server). You can use capistrano to copy error pages to web server root:

    # config/deploy.rb
    # Capistrano 3 only
    
    namespace :deploy do
      desc 'Copy compiled error pages to public'
      task :copy_error_pages do
        on roles(:all) do
          %w(404 500).each do |page|
            page_glob = "#{current_path}/public/#{fetch(:assets_prefix)}/#{page}*.html"
            # copy newest asset
            asset_file = capture :ruby, %Q{-e "print Dir.glob('#{page_glob}').max_by { |file| File.mtime(file) }"}
            if asset_file
              execute :cp, "#{asset_file} #{current_path}/public/#{page}.html"
            else
              error "Error #{page} asset does not exist"
            end
          end
        end
      end
      after :finishing, :copy_error_pages
    end
    

    And last thing. Tell web server to use these files for certain HTTP error codes (sample nginx configuration):

    error_page 500 502 503 504 /500.html;    
    error_page 404 /404.html;
    

    Sprocket 3 Update

    For Sprocket 3 you need something like this (tested with Rails 5):

    # config/environments/production.rb
    config.assets.configure do |env|
      env.register_transformer 'text/slim', 'text/html', Slim::Template
      env.register_mime_type 'text/slim', extensions: ['.html']
      env.register_engine '.slim', Slim::Template
    end
    
    # config/initializers/assets.rb
    Rails.application.config.assets.precompile += %w(404.html 500.html)
    Rails.application.config.assets.paths << Rails.root.join('app/assets/html')
    
    0 讨论(0)
提交回复
热议问题