Rails Raise Error 500
Contents |
here for a quick overview of the site Help Center
Rails Raise Custom Error
Detailed answers to any questions you might have Meta Discuss rails raise error in model the workings and policies of this site About Us Learn more about Stack Overflow
Rails Exception Types
the company Business Learn more about hiring developers or posting ads with us Stack Overflow Questions Jobs Documentation Tags Users Badges Ask Question x rails standard error Dismiss Join the Stack Overflow Community Stack Overflow is a community of 6.2 million programmers, just like you, helping each other. Join them; it only takes a minute: Sign up Internal Server Error 500 gets thrown instead of 404 while trying to access broken picture urls up vote rails raise internal server error 10 down vote favorite 7 We have a rails server with custom 404 and 500 pages setup using this tutorial here: http://ramblinglabs.com/blog/2012/01/rails-3-1-adding-custom-404-and-500-error-pages While it works nice and throws 404s for all kinds of paths, it generates internal server errors 500 while trying to access any kind of suffixed path like en/foo.png, en/foo.pdf, en/foo.xml, ... But something like en/file.foo throws 404. So only valid suffixes throw a 500. End of routes.rb: if Rails.application.config.consider_all_requests_local match '*not_found', to: 'errors#error_404' end application_controller.rb unless Rails.application.config.consider_all_requests_local rescue_from Exception, with: :render_500 rescue_from ActionController::RoutingError, with: :render_404 rescue_from ActionController::UnknownController, with: :render_404 rescue_from ::AbstractController::ActionNotFound, with: :render_404 rescue_from ActiveRecord::RecordNotFound, with: :render_404 end protected def render_404(exception) @not_found_path = exception.message respond_to do |format| format.html { render template: 'errors/error_404', layout: 'layouts/application', status: 404 } format.all { render nothing: true, status: 404 } end end def render_500(exception) logger.fatal(exception) respond_to do |format| format.html { render template: 'errors/error_500', layout: 'layouts/app
and rescuing custom errors in a Rails application. It's often useful to map custom Ruby errors to HTTP response status codes and have Rails render the
Rails Exceptions
appropriate HTML error pages. For example, you might have a controller that is acting rails raise 403 as a simple proxy to a third party service such as Twitter or Facebook, and you need any of the
Rails Custom Exception
HTTP errors encountered when calling those sites to be handled natively by your app. Another use case would be in a Service-oriented architecture (SOA), where you want any errors in your back end http://stackoverflow.com/questions/10280692/internal-server-error-500-gets-thrown-instead-of-404-while-trying-to-access-brok services propagated to your front end web application. In this post we'll demonstrate rescuing status errors in an imaginary proxy controller using the awesome Faraday gem. For the sake of brevity we've omitted the inclusion of tests though in the wild we'd build such a feature using TDD and our favourite test weapon, RSpec. Not Found To start, let's handle basic 404 Not Found errors that https://wearestac.com/blog/raising-and-rescuing-custom-errors-in-rails occur when calling a service. For this we'll need a custom error class that extends StandardError. # lib/errors/not_found.rb module Errors class NotFound < StandardError; end end Faraday provides a neat Rack-esque middleware feature. By creating our own custom middleware we can catch any Faraday 404s and raise our custom error. Furthermore, we can re-use the middleware anytime we need the same behaviour. # lib/errors/raise_error.rb module Errors class RaiseError < Faraday::Response::Middleware def on_complete(env) raise Errors::NotFound if env[:status] == 404 end end end Now for the proxy controller. # app/controllers/proxy_controller.rb class ProxyController < ApplicationController def index connection = Faraday.new(:url => 'http://someservice') do |f| f.adapter Faraday.default_adapter f.use Errors::RaiseError # Include custom middleware end response = connection.get('/some/resource') render :text => response.body end end At this point any NotFounds raised will still result in a 500 Internal Server Error in Rails. To alleviate this let's create a module that uses rescue_from, catches any custom NotFounds and renders the default 404 page. # lib/errors/rescue_error.rb module Errors module RescueError def self.included(base) base.rescue_from Errors::NotFound do |e| render "public/404", :status => 404 end end end end We can then mixin RescueError into our application controller and handle NotFounds app-wide. # app/controllers/application_controller.rb class ApplicationController < ActionController::Base include Errors::Rescu
Rails developers. So many different ways to manage control flow, load objects, respond in standard and erroneous ways. My opinion http://ngauthier.com/2011/09/using-exceptions-to-manage-control-flow.html up until recently was "I'll just put a bunch of conditionals in there for different situations."Recently, I've been working more on API endpoints and so responding with nice https://simonecarletti.com/blog/2009/11/re-raise-a-ruby-exception-in-a-rails-rescue_from-statement/ error messages has been more of a priority. I started using Exceptions more throughout my code thanks to Avdi Grimm, and I recently wrote and action that rails raise I'm particularly proud of. Check it out:# This controller's job is to exchange twitter credentials for Shortmail credentialsclass TwitterReverseAuthController < ApplicationController # First, let's make our own subclass of RuntimeError class Error < RuntimeError; end def api_key_exchange # Here are our required parameters. If any are missing we raise an error screen_name = params.fetch(:screen_name) { raise rails raise error Error.new('screen_name required') } token = params.fetch(:oauth_token) { raise Error.new('oauth_token required') } secret = params.fetch(:oauth_secret){ raise Error.new('oauth_secret required') } # OK now let's authenticate that user. If we can't find a valid user, raise an error @user = User.by_screen_name(screen_name).where( :oauth_token => token, :oauth_secret => secret ).first or raise Error.new('user not found') # Now we'll build a device. I'm not catching an exception on create! here because # It should never fail. (I.e. a failure is actually a 500 because we don't expect it) @device = Device.find_or_create_by_token!( params.slice(:token, :description).merge(:user_id => @user.id) ) render :json => { :api_key => @device.api_key } # Now I can simply catch any of my custom exceptions here rescue Error => e # And render their message back to the user render :json => { :error => e.message }, :status => :unprocessable_entity endendHere are the things I really like about this solution:The happy path is really clear because there's no if/else branchingErrors are really obvious because I'm raising an exception (as opposed to "els
of exceptions that are thrown in your application. For example, you want to rescue a ActiveRecord::StatementInvalid but not every ActiveRecord::StatementInvalid: just those ActiveRecord::StatementInvalid exceptions where the exception message matches a defined pattern. In this specific case, the following code won't work. class ApplicationController < ActionController::Base # ... rescue_from ActiveRecord::StatementInvalid, :with => :rescue_invalid_encoding protected def rescue_invalid_encoding # ... end end This is because a ActiveRecord::StatementInvalid is a generic error class and the rescue_from statement will catch any ActiveRecord::StatementInvalid indistinctly. But you don't want this, so you'll decide to go ahead and use the old-fashioned if school to filter the exception message. Only exceptions matching given message pattern should be catched. Any other exception should be released (or to use a technical jargon, rethrown). class ApplicationController < ActionController::Base # ... rescue_from ActiveRecord::StatementInvalid do |exception| if exception.message =~ /invalid byte sequence for encoding/ rescue_invalid_encoding(exception) else raise end end p