HomeToolsAbout

Exception

Exception handles every single exception that inherits from the Exception class and ultimately stops execution.

Error vs Exception

Error

  • indicates serious problem that a reasonable application should not try to catch.
  • an error is likely unable to be recovered during the program's execution.

Exception

  • indicates conditions that a reasonable application might want to catch.
  • disrupts the normal flow of the program, but it is typically expected and can be handled, recoverable.

Rescue

rescue_from

Rescues exceptions are raised in Controller actions.

  • rescues specifies exception raised.

rescue_from makes exception handling a requirement of the controller away from individual controller actions.

class ApplicationController < ActionController::Base rescue_from User::NotAuthorized, with: :deny_access protected def deny_access(exception) # ... end end

Do not rescue Exceptions

Never rescue broad level of exceptions.

  • Instead, rescue more specific exceptions that are reasonable to rescue.
begin @user = User.find_by!(id: 1) rescue Exception => e # Never do this as it will capture all Exceptions including every exception type in existence print e end # better... begin @user = User.find_by!(id: 1) rescue StandardError => e print e end # even better... begin @user = User.find_by!(id: 1) rescue ActiveRecord::RecordNotFound => e # Only rescues RecordNotFound exceptions, or classes that inherit from RecordNotFound print e end

If you don't specify any exception class, it defaults to StandardError class:

begin do_something() rescue => e puts e # e is an exception object containing info about the error. end # same as: begin do_something() rescue StandardError => e # Only your app's exceptions are swallowed. Things like SyntaxErrror are left alone. end

specific exceptions rescue (ok)

begin do_something() rescue ActiveRecord::RecordNotFound => e puts e # Only rescues RecordNotFound exceptions, or classes that inherit from RecordNotFound end


Every type of exception in Ruby is just a class.
 
In the example above, `ActiveRecord::RecordNotFound` is just the name of a class that follows certain conventions.

# Exception Tree

```shell
Exception
 NoMemoryError
 ScriptError
   LoadError
   NotImplementedError
   SyntaxError
 SignalException
   Interrupt
 StandardError
   ArgumentError
   IOError
     EOFError
   IndexError
   LocalJumpError
   NameError
     NoMethodError
   RangeError
     FloatDomainError
   RegexpError
   RuntimeError
   SecurityError
   SystemCallError
   SystemStackError
   ThreadError
   TypeError
   ZeroDivisionError
 SystemExit
 fatal

Custom Error Handlers

Handling errors can be defined at the base application controller through custom error handlers.

# base application controller class BaseApplicationController < ActionController::Base include CurrentController include Concerns::ActivityTracker::ContextProvider include Concerns::ErrorRescuer include UrlHelper # custom error rescuer module Concerns::ErrorRescuer extend ActiveSupport::Concern included do rescue_from StandardError, with: :render_500 rescue_from ActiveRecord::RecordNotFound, with: :render_404 rescue_from Pundit::NotAuthorizedError, with: :render_403 rescue_from ActionController::ParameterMissing, with: :render_422 rescue_from ActionController::RoutingError, with: :render_404 end def render_500(error = nil) raise error unless configatron.handle_all_errors! end end
AboutContact