SlideShare ist ein Scribd-Unternehmen logo
1 von 52
Error Handling in Ruby & Rails
       Simon Maynard - Bugsnag CTO
              @snmaynard
What is Bugsnag?

•   We help developers log and track their errors

•   Ruby was the first language we supported

•   Now support Python, PHP, Javascript, Node.js, iOS, Android & more!

•   Processing millions of errors every day
What is AN ERROR?

An error occurs when code is unable to complete the task asked of it.

  •   Asked to do the impossible
           Account.find(nil)


  •   A mistake in the code
            account = Account.new
            acccount.name #!?
What is AN ERROR?

•   An unexpected case
           case account.type
           when "free" then #
           when "paid" then #
           else
             # Unexpected!
           end

•   Failure of an external element
           # Database down!
           account.save
How to report an error?

•   Raise an exception

    •   Only when the error is truly exceptional

    •   If the error is unexpected, or a sign of bad code

    •   Raising should be unexpected, it’s slow
How to report an error?

•   Return an error value

    •   If its to be expected or part of "normal" operation

def find(id)
  raise InvalidIdError, "#{id} id an invalid id" unless validate_id(id)
  return data[id]
end
Raise Or Fail

•   You can use raise to raise an exception.

•   You can also use fail to raise an exception.

                   def func
                     fail "Not implemented"
                   rescue => e
                     raise unless e.message == "Not implemented"
                   end
Raise Syntax


 raise MyError.new("Something Broke")


is the same as
 raise MyError, "Something Broke"
Raise Syntax


 raise "Something Broke"


is the same as
 raise RuntimeError, "Something Broke"
Raise Syntax


 raise


is the same as
 raise RuntimeError
Raise Syntax


You can also pass a backtrace when raising an exception
 def assert(value)
   raise(RuntimeError, "Something broke", caller) unless value
 end
What does raise actually do?

•   Raise does four things,

    •   Builds an exception object

    •   Sets the backtrace

    •   Sets the global error object ($!)

    •   Starts unwinding the stack
How does raise build the exception?

You might think that raise does this
                         def raise(klass, msg, trace)
                           exception = klass.new(message)
                           # ...
                         end

But actually it does this...
                         def raise(klass, msg, trace)
                           exception = klass.exception(message)
                           # ...
                         end
How does raise build the exception?

•   Exception.exception

    •   The same as Exception.new()

•   Exception#exception

    •   With no arguments, it returns self

    •   With a message, it returns a new exception with the message set
How does raise build the exception?

This means we can implement our own exception methods
          class Account
            def exception(message="Bad Account!")
              ValidationError.new("#{message}: #{self.errors.inspect}")
            end
          end

then we can throw an instance of own object
          raise account unless account.save
Global Error Object
$! contains a reference to the exception currently being raised
   begin
     raise
   rescue
     puts $!.inspect
   end

You can also require “english” to use the slightly more readable
$ERROR_INFO
  require "english"
  begin
    raise
  rescue
    puts $ERROR_INFO.inspect
  end
rescue Syntax

 begin
 rescue MyError => error
 end

will rescue all MyError exceptions
rescue Syntax

 begin
 rescue => error
 end

is the same as
 begin
 rescue StandardError => error
 end
Rescue Syntax

 begin
 rescue
 end

is the same as
 begin
 rescue StandardError
 end
Rescue Syntax


You can also supply a list of classes to rescue
  begin
  rescue MyError, IOError => error
  end
One Line Rescue Syntax


  value = raise rescue "fallback_value"

is the same as
 value = begin
   raise
 rescue
   "fallback_value"
 end
Dynamic rescues
def match_message(regex)
  mod = Module.new
  (class << mod; self; end).instance_eval do
    define_method(:===) do |e|
      regex === e.message
    end
  end
  mod
end

begin
  raise "sample message"
rescue match_message(/sample/)
  # Ignore
end
Re-raising exception
 begin
   raise
 rescue
   raise
 end

is the same as
 begin
   raise
 rescue
   raise $!
 end
Raising in rescue

You can also change the exception message before re-raising


                        begin
                          raise
                        rescue => err
                          # Re raise with different message
                          raise err, “Different message”
                        end
Raising in rescue

You can raise in a rescue
                            def func
                              raise
                            rescue
                              raise "totally new exception"
                            end

You lose the context of the real error!

Don’t do this!
Raising in rescue
Instead you can keep a reference to the original exception
                  class MyError < StandardError
                    attr_accessor :original_exception
                    def initialize(msg, original_exception=$!)
                      super(msg)
                      self.original_exception = original_exception
                    end
                  end

                  def func
                    raise
                  rescue
                    raise MyError.new("Something broke")
                  end
Ensure Syntax

Ensure allows you to ensure that code is run, regardless of whether an exception
is raised or not.

                         begin
                           raise unless rand < 0.5
                         ensure
                           # Always run
                         end
ALTERNATIVE Syntax

You can also use these commands without a begin section

                         def func(arg)
                           raise
                         rescue
                           # Deal with exception
                         ensure
                           # Always run
                         end
Ensure Syntax

Be careful with return inside an ensure!


                   def func(arg)
                     raise
                   ensure
                     # This return swallows the exception
                     return 5
                   end
RETRY

You can also easily retry using the retry keyword
                        def func(arg)
                          attempts = 0
                          begin
                            attempts += 1
                            raise
                          rescue
                            retry if attempts < 3
                          end
                        end
exception hierarchy
                                     Exception


NoMemoryError   ScriptError   SignalException    SystemExit   StandardError   fatal

                                 Interrupt
                 LoadError                                    ArgumentError
                SyntaxError                                       IOError
                     ...                                        IndexError
                                                                     ...
Exception hierarchy

For example,
                 while true do
                   begin
                     line = STDIN.gets
                     # heavy processing
                   rescue Exception => e
                     puts "caught exception #{e}! ohnoes!"
                   end
                 end


This program is almost unkillable! Don’t catch Exception!
Exception Hierarchy

You can even prevent an exit call,
                            begin
                              exit(1) # Or abort()
                            rescue Exception
                              puts "Guess again!"
                            end
                            # Continue...




You can’t catch an exit!(1) however...
Raise is a method

•   Raise is just a method on Kernel

•   So we can override it!
Raise is a method

We can add debugging information to each raise
                    module RaiseDebug
                      def raise(*args)
                        super *args
                      rescue Exception
                        puts "Raising exception: #{$!.inspect}"
                        super *args
                      end
                    end
                    class Object
                      include RaiseDebug
                    end
Uncaught Errors

We can use a combination of $! and the ruby exit handler to log uncaught errors
                       at_exit do
                         if $!
                           open('error.log', 'a') do |log_file|
                             error = {
                               timestamp: Time.now.utc,
                               message:   $!.message,
                               trace:     $!.backtrace,
                             }
                             log_file.write(error.to_json)
                           end
                         end
                       end
Throw/Catch

Ruby can also throw, but its not for errors.

Use throw to unwrap the stack in a non-exceptional case, saves you from using
multiple break commands
                        INFINITY = 1.0 / 0.0
                        catch (:done) do
                          1.upto(INFINITY) do |i|
                            1.upto(INFINITY) do |j|
                              if some_condition
                                throw :done
                              end
                            end
                          end
                        end
How does rails deal with exceptions?

When there is an error in your rails app, ideally we want these things to happen

      •   500 page rendered to show the user something went wrong

      •   Error logged with enough information so we can fix it

      •   Rails to continue serving requests
How does rails deal with exceptions?

•   Rails uses a Rack app to process every request.

•   Rack apps have a middleware stack

•   You can easily add your own middleware so you can execute code on every
    request
    config.middleware.use(new_middleware, args)
    config.middleware.insert_before(existing_middleware, new_middleware, args)
    config.middleware.insert_after(existing_middleware, new_middleware, args)
    config.middleware.delete(middleware)
RACK Middleware
 Request           Response


      Middleware 1

      Middleware 2

      Middleware 3

      Middleware 4

           Rails App
Example RACK Middleware

Here is an example of a no-op middleware
                         module OurMiddleware
                           class Rack
                             def initialize(app)
                               @app = app
                             end

                             def call(env)
                               @app.call(env)
                             end
                           end
                         end
Example RACK Middleware

•   Initialize called when rails app starts

•   Takes a single parameter, which is the next middleware in the stack

•   Perform any other initialization for your middleware

                              def initialize(app)
                                @app = app
                              end
Example RACK Middleware

•   Call is called for every request

•   @app.call calls the next middleware in the stack (or your app itself)


                             def call(env)
                               response = @app.call(env)
                             end
Rendering a 500 page

•   Rails uses this to handle errors, for example in ShowExceptions middleware
     def call(env)
       @app.call(env)
     rescue Exception => exception
       raise exception if env['action_dispatch.show_exceptions'] == false
       render_exception(env, exception)
     end



•   Rails rescues the exception here, and renders a nice 500 error page
Bugsnag Logging middleware

•   Here is a simplified version of the Bugsnag error logging middleware

                           def call(env)
                             @app.call(env)
                           rescue Exception => exception
                             Bugsnag.notify(exception)
                             raise
                           end


•   But you need to make sure this goes in you middleware stack JUST before you
    render the 500 page!
SHOW The middleware stack

•   Rails has given you an awesome tool to show your middleware stack
                   $ rake middleware
                   ...
                   use ActionDispatch::ShowExceptions
                   use ActionDispatch::DebugExceptions
                   use Bugsnag::Rack
                   ...
                   use ActionDispatch::Cookies
                   use ActionDispatch::Session::CookieStore
                   use ActionDispatch::Flash
                   use ActionDispatch::ParamsParser
                   ...
                   run YourApp::Application.routes
Better Errors




•   https://github.com/charliesome/better_errors

•   Better version of DebugExceptions, used in development on Rails

•   Allows you to debug crashes when they happen
Hammertime




•   https://github.com/avdi/hammertime

•   Allows you to debug exception raises in real time in Ruby apps
PRY RESCUE




•   https://github.com/ConradIrwin/pry-rescue

•   Allows you to debug uncaught exceptions in real time in Ruby apps
Bugsnag




•   http://bugsnag.com

•   Tracks and groups your errors from development and production

•   Get notified when someone on production sees a crash!
Find out more

•   Avdi Grimm has a great book on Ruby failure handling - I highly recommend it
    (http://exceptionalruby.com/)

•   When looking into rails error handling, delving into Rails source is recommended.
Questions?
Check out www.bugsnag.com

Weitere ähnliche Inhalte

Was ist angesagt?

Prevencao do HIV e Outras ISTs Identificando as Oportunidades de Acao
Prevencao do HIV e Outras ISTs Identificando as Oportunidades de AcaoPrevencao do HIV e Outras ISTs Identificando as Oportunidades de Acao
Prevencao do HIV e Outras ISTs Identificando as Oportunidades de AcaoAlexandre Naime Barbosa
 
Classificação, coleta, transporte, armazenamento, tratamento e destino final ...
Classificação, coleta, transporte, armazenamento, tratamento e destino final ...Classificação, coleta, transporte, armazenamento, tratamento e destino final ...
Classificação, coleta, transporte, armazenamento, tratamento e destino final ...MendesAanjossMeendes
 
Cópia de ENFERMAGEM - MICROBIOLOGIA E PARASITOLOGIA 4.pdf
Cópia de ENFERMAGEM -  MICROBIOLOGIA E PARASITOLOGIA 4.pdfCópia de ENFERMAGEM -  MICROBIOLOGIA E PARASITOLOGIA 4.pdf
Cópia de ENFERMAGEM - MICROBIOLOGIA E PARASITOLOGIA 4.pdfCamilaAlcantara18
 
Clinica MĂŠdica.pptx
Clinica MĂŠdica.pptxClinica MĂŠdica.pptx
Clinica MĂŠdica.pptxMirna Kathary
 
Clinica medica protocolo completo
Clinica medica   protocolo completoClinica medica   protocolo completo
Clinica medica protocolo completoKeila Santos
 
Atuação do nutricionista em unidades de alimentação e nutrição
Atuação do nutricionista em unidades de alimentação e nutriçãoAtuação do nutricionista em unidades de alimentação e nutrição
Atuação do nutricionista em unidades de alimentação e nutriçãoHelen Magalhães Messias
 
Segurança na Cadeia Medicamentosa
Segurança na Cadeia MedicamentosaSegurança na Cadeia Medicamentosa
Segurança na Cadeia MedicamentosaMarco Lamim
 
Dimensionamento de Pessoal de Enfermagem - campo mourao
Dimensionamento de Pessoal de Enfermagem - campo mouraoDimensionamento de Pessoal de Enfermagem - campo mourao
Dimensionamento de Pessoal de Enfermagem - campo mouraoToni Magalhaes
 
AULA 1 - UTI GERAL ESTRUTURA.pdf
AULA 1 - UTI GERAL ESTRUTURA.pdfAULA 1 - UTI GERAL ESTRUTURA.pdf
AULA 1 - UTI GERAL ESTRUTURA.pdfmauromaumau
 
Corrimentos vaginais
Corrimentos vaginaisCorrimentos vaginais
Corrimentos vaginaisInaiara Bragante
 
Atividades no prĂŠ e trans operatĂłrio
Atividades no prĂŠ e trans operatĂłrioAtividades no prĂŠ e trans operatĂłrio
Atividades no prÊ e trans operatórioSilvânia Galdino
 
Sintomas do sistema digestĂłrio
Sintomas do sistema digestĂłrio Sintomas do sistema digestĂłrio
Sintomas do sistema digestĂłrio pauloalambert
 
Apostila de biossegurança nas açþes de enfermagem
Apostila de biossegurança nas açþes de enfermagemApostila de biossegurança nas açþes de enfermagem
Apostila de biossegurança nas açþes de enfermagemDouglas Oliveira
 
A ENFERMAGEM FRENTE A LIDERANÇA E O TRABALHO.pptx
A ENFERMAGEM FRENTE A LIDERANÇA E O TRABALHO.pptxA ENFERMAGEM FRENTE A LIDERANÇA E O TRABALHO.pptx
A ENFERMAGEM FRENTE A LIDERANÇA E O TRABALHO.pptxViniciusSouzaalves
 
atribuição da enfermagem.pptx
atribuição da enfermagem.pptxatribuição da enfermagem.pptx
atribuição da enfermagem.pptxssuser51d27c1
 
Disciplina de ClĂ­nica MĂŠdica l -PropedĂŞutica
Disciplina de ClĂ­nica MĂŠdica l -PropedĂŞuticaDisciplina de ClĂ­nica MĂŠdica l -PropedĂŞutica
Disciplina de ClĂ­nica MĂŠdica l -PropedĂŞuticaPaulo Alambert
 

Was ist angesagt? (20)

Prevencao do HIV e Outras ISTs Identificando as Oportunidades de Acao
Prevencao do HIV e Outras ISTs Identificando as Oportunidades de AcaoPrevencao do HIV e Outras ISTs Identificando as Oportunidades de Acao
Prevencao do HIV e Outras ISTs Identificando as Oportunidades de Acao
 
Classificação, coleta, transporte, armazenamento, tratamento e destino final ...
Classificação, coleta, transporte, armazenamento, tratamento e destino final ...Classificação, coleta, transporte, armazenamento, tratamento e destino final ...
Classificação, coleta, transporte, armazenamento, tratamento e destino final ...
 
Cópia de ENFERMAGEM - MICROBIOLOGIA E PARASITOLOGIA 4.pdf
Cópia de ENFERMAGEM -  MICROBIOLOGIA E PARASITOLOGIA 4.pdfCópia de ENFERMAGEM -  MICROBIOLOGIA E PARASITOLOGIA 4.pdf
Cópia de ENFERMAGEM - MICROBIOLOGIA E PARASITOLOGIA 4.pdf
 
Clinica MĂŠdica.pptx
Clinica MĂŠdica.pptxClinica MĂŠdica.pptx
Clinica MĂŠdica.pptx
 
HIV Aids Caso Clinico
HIV Aids Caso ClinicoHIV Aids Caso Clinico
HIV Aids Caso Clinico
 
SLIDE DST..pptx
SLIDE DST..pptxSLIDE DST..pptx
SLIDE DST..pptx
 
Aids na 3a. idade.Ppt
Aids na 3a. idade.PptAids na 3a. idade.Ppt
Aids na 3a. idade.Ppt
 
1512
15121512
1512
 
Clinica medica protocolo completo
Clinica medica   protocolo completoClinica medica   protocolo completo
Clinica medica protocolo completo
 
Atuação do nutricionista em unidades de alimentação e nutrição
Atuação do nutricionista em unidades de alimentação e nutriçãoAtuação do nutricionista em unidades de alimentação e nutrição
Atuação do nutricionista em unidades de alimentação e nutrição
 
Segurança na Cadeia Medicamentosa
Segurança na Cadeia MedicamentosaSegurança na Cadeia Medicamentosa
Segurança na Cadeia Medicamentosa
 
Dimensionamento de Pessoal de Enfermagem - campo mourao
Dimensionamento de Pessoal de Enfermagem - campo mouraoDimensionamento de Pessoal de Enfermagem - campo mourao
Dimensionamento de Pessoal de Enfermagem - campo mourao
 
AULA 1 - UTI GERAL ESTRUTURA.pdf
AULA 1 - UTI GERAL ESTRUTURA.pdfAULA 1 - UTI GERAL ESTRUTURA.pdf
AULA 1 - UTI GERAL ESTRUTURA.pdf
 
Corrimentos vaginais
Corrimentos vaginaisCorrimentos vaginais
Corrimentos vaginais
 
Atividades no prĂŠ e trans operatĂłrio
Atividades no prĂŠ e trans operatĂłrioAtividades no prĂŠ e trans operatĂłrio
Atividades no prĂŠ e trans operatĂłrio
 
Sintomas do sistema digestĂłrio
Sintomas do sistema digestĂłrio Sintomas do sistema digestĂłrio
Sintomas do sistema digestĂłrio
 
Apostila de biossegurança nas açþes de enfermagem
Apostila de biossegurança nas açþes de enfermagemApostila de biossegurança nas açþes de enfermagem
Apostila de biossegurança nas açþes de enfermagem
 
A ENFERMAGEM FRENTE A LIDERANÇA E O TRABALHO.pptx
A ENFERMAGEM FRENTE A LIDERANÇA E O TRABALHO.pptxA ENFERMAGEM FRENTE A LIDERANÇA E O TRABALHO.pptx
A ENFERMAGEM FRENTE A LIDERANÇA E O TRABALHO.pptx
 
atribuição da enfermagem.pptx
atribuição da enfermagem.pptxatribuição da enfermagem.pptx
atribuição da enfermagem.pptx
 
Disciplina de ClĂ­nica MĂŠdica l -PropedĂŞutica
Disciplina de ClĂ­nica MĂŠdica l -PropedĂŞuticaDisciplina de ClĂ­nica MĂŠdica l -PropedĂŞutica
Disciplina de ClĂ­nica MĂŠdica l -PropedĂŞutica
 

Ähnlich wie Ruby & Rails Error Handling

Exception Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in RubyException Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in RubyWen-Tien Chang
 
21 ruby exceptions
21 ruby exceptions21 ruby exceptions
21 ruby exceptionsWalker Maidana
 
Exceptions in Ruby - Tips and Tricks
Exceptions in Ruby - Tips and TricksExceptions in Ruby - Tips and Tricks
Exceptions in Ruby - Tips and TricksDimelo R&D Team
 
Code Fast, die() Early, Throw Structured Exceptions
Code Fast, die() Early, Throw Structured ExceptionsCode Fast, die() Early, Throw Structured Exceptions
Code Fast, die() Early, Throw Structured ExceptionsJohn Anderson
 
Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)Wen-Tien Chang
 
exceptions in java
exceptions in javaexceptions in java
exceptions in javajaveed_mhd
 
Exceptions in java
Exceptions in javaExceptions in java
Exceptions in javaRajkattamuri
 
Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Jalpesh Vasa
 
exception handling.pptx
exception handling.pptxexception handling.pptx
exception handling.pptxAbinayaC11
 
Ruby Gotchas
Ruby GotchasRuby Gotchas
Ruby GotchasDave Aronson
 
Exceptions in java
Exceptions in javaExceptions in java
Exceptions in javaManav Prasad
 
Code Fast, Die Young, Throw Structured Exceptions
Code Fast, Die Young, Throw Structured ExceptionsCode Fast, Die Young, Throw Structured Exceptions
Code Fast, Die Young, Throw Structured ExceptionsJohn Anderson
 
Metaprogramming in Ruby
Metaprogramming in RubyMetaprogramming in Ruby
Metaprogramming in RubyConFoo
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogrammingjoshbuddy
 
Ruby Gotchas
Ruby GotchasRuby Gotchas
Ruby GotchasDave Aronson
 
Ruby Intro {spection}
Ruby Intro {spection}Ruby Intro {spection}
Ruby Intro {spection}Christian KAKESA
 
New land of error handling in swift
New land of error handling in swiftNew land of error handling in swift
New land of error handling in swiftTsungyu Yu
 
A exception ekon16
A exception ekon16A exception ekon16
A exception ekon16Max Kleiner
 

Ähnlich wie Ruby & Rails Error Handling (20)

Exception Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in RubyException Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in Ruby
 
21 ruby exceptions
21 ruby exceptions21 ruby exceptions
21 ruby exceptions
 
Exceptions in Ruby - Tips and Tricks
Exceptions in Ruby - Tips and TricksExceptions in Ruby - Tips and Tricks
Exceptions in Ruby - Tips and Tricks
 
Code Fast, die() Early, Throw Structured Exceptions
Code Fast, die() Early, Throw Structured ExceptionsCode Fast, die() Early, Throw Structured Exceptions
Code Fast, die() Early, Throw Structured Exceptions
 
Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)
 
Introduction to php exception and error management
Introduction to php  exception and error managementIntroduction to php  exception and error management
Introduction to php exception and error management
 
exceptions in java
exceptions in javaexceptions in java
exceptions in java
 
Exceptions in java
Exceptions in javaExceptions in java
Exceptions in java
 
8 Exception Handling
8 Exception Handling8 Exception Handling
8 Exception Handling
 
Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Object Oriented PHP - PART-2
Object Oriented PHP - PART-2
 
exception handling.pptx
exception handling.pptxexception handling.pptx
exception handling.pptx
 
Ruby Gotchas
Ruby GotchasRuby Gotchas
Ruby Gotchas
 
Exceptions in java
Exceptions in javaExceptions in java
Exceptions in java
 
Code Fast, Die Young, Throw Structured Exceptions
Code Fast, Die Young, Throw Structured ExceptionsCode Fast, Die Young, Throw Structured Exceptions
Code Fast, Die Young, Throw Structured Exceptions
 
Metaprogramming in Ruby
Metaprogramming in RubyMetaprogramming in Ruby
Metaprogramming in Ruby
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogramming
 
Ruby Gotchas
Ruby GotchasRuby Gotchas
Ruby Gotchas
 
Ruby Intro {spection}
Ruby Intro {spection}Ruby Intro {spection}
Ruby Intro {spection}
 
New land of error handling in swift
New land of error handling in swiftNew land of error handling in swift
New land of error handling in swift
 
A exception ekon16
A exception ekon16A exception ekon16
A exception ekon16
 

KĂźrzlich hochgeladen

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 

KĂźrzlich hochgeladen (20)

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 

Ruby & Rails Error Handling

  • 1. Error Handling in Ruby & Rails Simon Maynard - Bugsnag CTO @snmaynard
  • 2. What is Bugsnag? • We help developers log and track their errors • Ruby was the first language we supported • Now support Python, PHP, Javascript, Node.js, iOS, Android & more! • Processing millions of errors every day
  • 3. What is AN ERROR? An error occurs when code is unable to complete the task asked of it. • Asked to do the impossible Account.find(nil) • A mistake in the code account = Account.new acccount.name #!?
  • 4. What is AN ERROR? • An unexpected case case account.type when "free" then # when "paid" then # else # Unexpected! end • Failure of an external element # Database down! account.save
  • 5. How to report an error? • Raise an exception • Only when the error is truly exceptional • If the error is unexpected, or a sign of bad code • Raising should be unexpected, it’s slow
  • 6. How to report an error? • Return an error value • If its to be expected or part of "normal" operation def find(id) raise InvalidIdError, "#{id} id an invalid id" unless validate_id(id) return data[id] end
  • 7. Raise Or Fail • You can use raise to raise an exception. • You can also use fail to raise an exception. def func fail "Not implemented" rescue => e raise unless e.message == "Not implemented" end
  • 8. Raise Syntax raise MyError.new("Something Broke") is the same as raise MyError, "Something Broke"
  • 9. Raise Syntax raise "Something Broke" is the same as raise RuntimeError, "Something Broke"
  • 10. Raise Syntax raise is the same as raise RuntimeError
  • 11. Raise Syntax You can also pass a backtrace when raising an exception def assert(value) raise(RuntimeError, "Something broke", caller) unless value end
  • 12. What does raise actually do? • Raise does four things, • Builds an exception object • Sets the backtrace • Sets the global error object ($!) • Starts unwinding the stack
  • 13. How does raise build the exception? You might think that raise does this def raise(klass, msg, trace) exception = klass.new(message) # ... end But actually it does this... def raise(klass, msg, trace) exception = klass.exception(message) # ... end
  • 14. How does raise build the exception? • Exception.exception • The same as Exception.new() • Exception#exception • With no arguments, it returns self • With a message, it returns a new exception with the message set
  • 15. How does raise build the exception? This means we can implement our own exception methods class Account def exception(message="Bad Account!") ValidationError.new("#{message}: #{self.errors.inspect}") end end then we can throw an instance of own object raise account unless account.save
  • 16. Global Error Object $! contains a reference to the exception currently being raised begin raise rescue puts $!.inspect end You can also require “english” to use the slightly more readable $ERROR_INFO require "english" begin raise rescue puts $ERROR_INFO.inspect end
  • 17. rescue Syntax begin rescue MyError => error end will rescue all MyError exceptions
  • 18. rescue Syntax begin rescue => error end is the same as begin rescue StandardError => error end
  • 19. Rescue Syntax begin rescue end is the same as begin rescue StandardError end
  • 20. Rescue Syntax You can also supply a list of classes to rescue begin rescue MyError, IOError => error end
  • 21. One Line Rescue Syntax value = raise rescue "fallback_value" is the same as value = begin raise rescue "fallback_value" end
  • 22. Dynamic rescues def match_message(regex) mod = Module.new (class << mod; self; end).instance_eval do define_method(:===) do |e| regex === e.message end end mod end begin raise "sample message" rescue match_message(/sample/) # Ignore end
  • 23. Re-raising exception begin raise rescue raise end is the same as begin raise rescue raise $! end
  • 24. Raising in rescue You can also change the exception message before re-raising begin raise rescue => err # Re raise with different message raise err, “Different message” end
  • 25. Raising in rescue You can raise in a rescue def func raise rescue raise "totally new exception" end You lose the context of the real error! Don’t do this!
  • 26. Raising in rescue Instead you can keep a reference to the original exception class MyError < StandardError attr_accessor :original_exception def initialize(msg, original_exception=$!) super(msg) self.original_exception = original_exception end end def func raise rescue raise MyError.new("Something broke") end
  • 27. Ensure Syntax Ensure allows you to ensure that code is run, regardless of whether an exception is raised or not. begin raise unless rand < 0.5 ensure # Always run end
  • 28. ALTERNATIVE Syntax You can also use these commands without a begin section def func(arg) raise rescue # Deal with exception ensure # Always run end
  • 29. Ensure Syntax Be careful with return inside an ensure! def func(arg) raise ensure # This return swallows the exception return 5 end
  • 30. RETRY You can also easily retry using the retry keyword def func(arg) attempts = 0 begin attempts += 1 raise rescue retry if attempts < 3 end end
  • 31. exception hierarchy Exception NoMemoryError ScriptError SignalException SystemExit StandardError fatal Interrupt LoadError ArgumentError SyntaxError IOError ... IndexError ...
  • 32. Exception hierarchy For example, while true do begin line = STDIN.gets # heavy processing rescue Exception => e puts "caught exception #{e}! ohnoes!" end end This program is almost unkillable! Don’t catch Exception!
  • 33. Exception Hierarchy You can even prevent an exit call, begin exit(1) # Or abort() rescue Exception puts "Guess again!" end # Continue... You can’t catch an exit!(1) however...
  • 34. Raise is a method • Raise is just a method on Kernel • So we can override it!
  • 35. Raise is a method We can add debugging information to each raise module RaiseDebug def raise(*args) super *args rescue Exception puts "Raising exception: #{$!.inspect}" super *args end end class Object include RaiseDebug end
  • 36. Uncaught Errors We can use a combination of $! and the ruby exit handler to log uncaught errors at_exit do if $! open('error.log', 'a') do |log_file| error = { timestamp: Time.now.utc, message: $!.message, trace: $!.backtrace, } log_file.write(error.to_json) end end end
  • 37. Throw/Catch Ruby can also throw, but its not for errors. Use throw to unwrap the stack in a non-exceptional case, saves you from using multiple break commands INFINITY = 1.0 / 0.0 catch (:done) do 1.upto(INFINITY) do |i| 1.upto(INFINITY) do |j| if some_condition throw :done end end end end
  • 38. How does rails deal with exceptions? When there is an error in your rails app, ideally we want these things to happen • 500 page rendered to show the user something went wrong • Error logged with enough information so we can fix it • Rails to continue serving requests
  • 39. How does rails deal with exceptions? • Rails uses a Rack app to process every request. • Rack apps have a middleware stack • You can easily add your own middleware so you can execute code on every request config.middleware.use(new_middleware, args) config.middleware.insert_before(existing_middleware, new_middleware, args) config.middleware.insert_after(existing_middleware, new_middleware, args) config.middleware.delete(middleware)
  • 40. RACK Middleware Request Response Middleware 1 Middleware 2 Middleware 3 Middleware 4 Rails App
  • 41. Example RACK Middleware Here is an example of a no-op middleware module OurMiddleware class Rack def initialize(app) @app = app end def call(env) @app.call(env) end end end
  • 42. Example RACK Middleware • Initialize called when rails app starts • Takes a single parameter, which is the next middleware in the stack • Perform any other initialization for your middleware def initialize(app) @app = app end
  • 43. Example RACK Middleware • Call is called for every request • @app.call calls the next middleware in the stack (or your app itself) def call(env) response = @app.call(env) end
  • 44. Rendering a 500 page • Rails uses this to handle errors, for example in ShowExceptions middleware def call(env) @app.call(env) rescue Exception => exception raise exception if env['action_dispatch.show_exceptions'] == false render_exception(env, exception) end • Rails rescues the exception here, and renders a nice 500 error page
  • 45. Bugsnag Logging middleware • Here is a simplified version of the Bugsnag error logging middleware def call(env) @app.call(env) rescue Exception => exception Bugsnag.notify(exception) raise end • But you need to make sure this goes in you middleware stack JUST before you render the 500 page!
  • 46. SHOW The middleware stack • Rails has given you an awesome tool to show your middleware stack $ rake middleware ... use ActionDispatch::ShowExceptions use ActionDispatch::DebugExceptions use Bugsnag::Rack ... use ActionDispatch::Cookies use ActionDispatch::Session::CookieStore use ActionDispatch::Flash use ActionDispatch::ParamsParser ... run YourApp::Application.routes
  • 47. Better Errors • https://github.com/charliesome/better_errors • Better version of DebugExceptions, used in development on Rails • Allows you to debug crashes when they happen
  • 48. Hammertime • https://github.com/avdi/hammertime • Allows you to debug exception raises in real time in Ruby apps
  • 49. PRY RESCUE • https://github.com/ConradIrwin/pry-rescue • Allows you to debug uncaught exceptions in real time in Ruby apps
  • 50. Bugsnag • http://bugsnag.com • Tracks and groups your errors from development and production • Get notified when someone on production sees a crash!
  • 51. Find out more • Avdi Grimm has a great book on Ruby failure handling - I highly recommend it (http://exceptionalruby.com/) • When looking into rails error handling, delving into Rails source is recommended.

Hinweis der Redaktion

  1. experience of monitoring apps at scale heyzap
  2. example errors
  3. Performance
  4. Return an error value if its common or people will use to test Validation function shouldnt raise if invalid e.g mongoid find raising by default, at least you can change if you want
  5. raise = fail raise common some use fail to be when failing for first time, raise in rescue blocks
  6. exception is like to_s, but for exceptions
  7. Can attach exception methods to objects easily, so they can be raised
  8. These are just examples, empty rescue blocks are a code smell, at least have a log in there!
  9. Bad as it catches all StandardErrors, you should catch explicit exception types, more on that later
  10. Rescue calls === on the error and the object passed to rescue, so we can override
  11. This is a common pattern in ruby, getting more popular - rails does it when you have an error in your view for example converts to template error
  12. Exception hierarchy shows why you should never catch exception
  13. Be specific when you catch something
  14. Note here I rescue exception, but I always re-raise :-)
  15. Sinatra uses this when using etags i believe, to prevent recalculating a still valid response
  16. Middleware performance is important Crashes in middleware are very bad