Raising an Exception

Raising an Exception

Credit: Steve Arneil


An error has occurred and your code can't keep running. You want to indicate the error and let some other piece of code handle it.


Raise an exception by calling the Kernel#raise method with a description of the error. Calling the raise method interrupts the flow of execution.

The following method raises an exception whenever it's called. Its second message will never be printed:

	def raise_exception
	  puts 'I am before the raise.'
	  raise 'An error has occurred.'
	  puts 'I am after the raise.'

	# I am before the raise.
	# RuntimeError: An error has occurred


Here's a method, inverse, that returns the inverse of a number x. It does some basic error checking by raising an exception unless x is a number:

	def inverse(x)
	  raise "Argument is not numeric" unless x.is_a? Numeric
	  1.0 / x

When you pass in a reasonable value of x, all is well:

	inverse(2)                                      # => 0.5

When x is not a number, the method raises an exception:

	inverse('not a number')
	# RuntimeError: Argument is not numeric

An exception is an object, and the Kernel#raise method creates an instance of an exception class. By default, Kernel#raise creates an exception of RuntimeError class, which is a subclass of StandardError. This in turn is a subclass of Exception, the superclass of all exception classes. You can list all the standard exception classes by starting a Ruby session and executing code like this:

	ObjectSpace.each_object(Class) do |x|
	  puts x if x.ancestors.member? Exception

This variant lists only the better-known exception classes:

	ObjectSpace.each_object(Class) { |x| puts x if x.name =~ /Error$/ }
	# SystemStackError
	# LocalJumpError
	# EOFError
	# IOError
	# RegexpError
	# …

To raise an exception of a specific class, you can pass in the class name as an argument to raise. RuntimeError is kind of generic for the inverse method's check against x. The problem is there is actually a problem with one of the arguments passed into the method. A more aptly named exception class for that check would be ArgumentError:

	def inverse(x)
	  raise ArgumentError, 'Argument is not numeric' unless x.is_a? Numeric
	  1.0 / x

To be even more specific about an error, you can define your own Exception subclass:

	class NotInvertibleError < StandardError

The implementation of inverse method would then become:

	def inverse(x)
	  raise NotInvertibleError, 'Argument is not numeric' unless x.is_a? Numeric
	  1.0 / x

	inverse('not a number')
	# NotInvertibleError: Argument is not numeric

In some other programming languages, exceptions are "thrown." In Ruby, they are not thrown but "raised." Ruby does have a Kernel#throw method, but it has nothing to do with exceptions. See Recipe 7.8 for an example of tHRow, as opposed to raise.

See Also

  • Recipe 7.8, "Stopping an Iteration"

  • Recipe 17.2, " Raising an Exception"

  • Recipe 17.3, "Handling an Exception"

 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows