Error Handling In Ruby
Contents |
Contents Resources Blog Contact Design and Theory Exception and Error Handling How a program recovers from unexpected (and expected) errors Chapter outline Demonstrating exceptions The Begin...Rescue block Flow of exception handling Exception and Error Classes Further reading Previous
Ruby String
Chapter: Image Manipulation Next Chapter: Object-Oriented Concepts Planking on the High Line. (Photo by Dan rails error handling Nguyen) This was a chapter that I decided to include at the last minute. It's not complete but at least you can be
Ruby Array
aware of basic exception handling. No matter how carefully you code your script, your program is prone to failure for reasons beyond your control. A website that your script scrapes may suddenly be down. Or someone sharing the same http://rubylearning.com/satishtalim/ruby_exceptions.html hard drive may delete a file your program is supposed to read from. Circumstances such as these will crash your program. For any kind of long continuous task that you don't want to baby-sit and manually restart, you will need to write some exception-handling code to tell the program how to carry on when things go wrong. Demonstrating exceptions Before the formal description of the the begin/rescue block, let's walk through a couple examples of it in http://ruby.bastardsbook.com/chapters/exception-handling action. At a skin-deep level, it behaves nearly the same as the if/else construct. Skipping past an error The Exception class handles nearly every kind of hiccup that might occur during runtime, including syntax screwups and incorrect type handling. We learned early on that adding numbers and strings with no type conversion would crash a program: a = 10 b = "42" a + b The attempted arithmetic results in this error: The begin/rescue block is typically used on code in which you anticipate errors. There's only one line here for us to worry about: a = 10 b = "42" begin a + b rescue puts "Could not add variables a (#{a.class}) and b (#{b.class})" else puts "a + b is #{a + b}" end Executing the revised code gets us this: Two obvious differences from the first try: The puts statement in the rescue clause executed. And more importantly, the Ruby program did not crash. Let's feed this simple operation with an array of values of different types to see how the else clause comes into play: values = [42, 'a', 'r', 9, 5, 10022, 8.7, "sharon", "Libya", "Mars", "12", 98, rand + rand, {:dog=>'cat'}, 100, nil, 200.0000, Object, 680, 3.14, "Steve", 78, "Argo"].shuffle while values.length > 0 a = values.pop b = values.pop begin a + b rescue puts "Could not add variables a (#{a.class}) a
users never enter incorrect data, and resources are plentiful and cheap. Well, that's about to change. Welcome to the real world! In the real world, errors happen. Good http://phrogz.net/programmingruby/tut_exceptions.html programs (and programmers) anticipate them and arrange to handle them gracefully. This isn't https://ruby-doc.org/core-2.2.0/Exception.html always as easy as it might be. Often the code that detects an error does not have the context to know what to do about it. For example, attempting to open a file that doesn't exist is acceptable in some circumstances and is a fatal error at other times. What's error handling your file-handling module to do? The traditional approach is to use return codes. The open method returns some specific value to say it failed. This value is then propagated back through the layers of calling routines until someone wants to take responsibility for it. The problem with this approach is that managing all these error codes can be a pain. If a error handling in function calls open, then read, and finally close, and each can return an error indication, how can the function distinguish these error codes in the value it returns to its caller? To a large extent, exceptions solve this problem. Exceptions let you package up information about an error into an object. That exception object is then propagated back up the calling stack automatically until the runtime system finds code that explicitly declares that it knows how to handle that type of exception. The Exception Class The package that contains the information about an exception is an object of class Exception, or one of class Exception's children. Ruby predefines a tidy hierarchy of exceptions, shown in Figure 8.1. As we'll see later, this hierarchy makes handling exceptions considerably easier. Figure 8.1 not available... When you need to raise an exception, you can use one of the built-in Exception classes, or you can create one of your own. If you create your own, you might want to make it a subclass of StandardError or one of its children. If you don't, your exception won't be caught by def
contributing.rdoc contributors.rdoc dtrace_probes.rdoc globals.rdoc keywords.rdoc maintainers.rdoc marshal.rdoc regexp.rdoc security.rdoc standard_library.rdoc syntax.rdoc assignment.rdoc calling_methods.rdoc control_expressions.rdoc exceptions.rdoc literals.rdoc methods.rdoc miscellaneous.rdoc modules_and_classes.rdoc precedence.rdoc refinements.rdoc README.ja.rdoc README.rdoc Class/Module Index Quicksearch ArgumentError Array BasicObject Bignum Binding Class Comparable Complex Complex::compatible ConditionVariable Continuation Data Dir ENV EOFError Encoding Encoding::CompatibilityError Encoding::Converter Encoding::ConverterNotFoundError Encoding::InvalidByteSequenceError Encoding::UndefinedConversionError EncodingError Enumerable Enumerator Enumerator::Generator Enumerator::Lazy Enumerator::Yielder Errno Exception FalseClass Fiber FiberError File File::Constants File::Stat FileTest Fixnum Float FloatDomainError GC GC::Profiler Hash IO IO::EAGAINWaitReadable IO::EAGAINWaitWritable IO::EINPROGRESSWaitReadable IO::EINPROGRESSWaitWritable IO::EWOULDBLOCKWaitReadable IO::EWOULDBLOCKWaitWritable IO::WaitReadable IO::WaitWritable IOError IndexError Integer Interrupt Kernel KeyError LoadError LocalJumpError Marshal MatchData Math Math::DomainError Method Module Mutex NameError NilClass NoMemoryError NoMethodError NotImplementedError Numeric Object ObjectSpace ObjectSpace::WeakMap Proc Process Process::GID Process::Status Process::Sys Process::UID Process::Waiter Queue Random Range RangeError Rational Rational::compatible Regexp RegexpError RubyVM RubyVM::Env RubyVM::InstructionSequence RuntimeError ScriptError SecurityError Signal SignalException SizedQueue StandardError StopIteration String Struct Symbol SyntaxError SystemCallError SystemExit SystemStackError Thread Thread::Backtrace::Location ThreadError