Ruby error

In Ruby, all exceptions and errors are extensions of the Exception class. While this may seem intuitive, exception handling in Ruby is a touch more nuanced than you might expect thanks to the designed hierarchy of Ruby exceptions.

The begin-rescue

Similar to PHP’s try-catch, Ruby’s exception handling begins with the begin-rescue block. In a nutshell, the begin-rescue is a code block that can be used to deal with raised exceptions without interrupting program execution. In other words, you can begin to execute a block of code, and rescue any exceptions that are raised.

Rescuing Exceptions

By default, begin-rescue rescues every instance of the StandardError class. This includes no method errors, type errors, runtime errors, and every custom error that is intended to be rescued within a Ruby application (see Raising Exceptions in Ruby for more information). To rescue every StandardError, simply wrap the designated section of code in a begin-rescue block:

begin

  # …

rescue => e

  # …

end

When a StandardError exception is raised within the begin block, an instance of it will be passed to the rescue block as the variable e (for more information about the structure of Ruby’s Exception class, see Raising Exceptions in Ruby).

Errors & magic variables

Ruby provides 2 magic variables that are set when an exception is raised:

The $! variable that contains the raised exception

The $@ variable that contains the exception backtrace

produces

NoMethodError: undefined method `odd?’ for “my string”:String

/workspace.rb:87:in `eval’

/workspace.rb:87:in `evaluate’

/bin/irb:11:in `<main>’

These variables are cleared — set to nil — when the rescue block ends.

Ruby’s Internal Exceptions

There are only a handful of internal Exceptions that Ruby uses, and like we already mentioned, rescuing all of them indiscriminately is usually not a good idea (although rescuing some of them individually is fairly common). These are Ruby’s internal exceptions.

NoMemoryError

NoMemoryError is raised by Ruby when memory allocation fails. This does not mean that the system is out of memory; rather, it indicates that Ruby attempted to initialize an object that would consume more memory than the system allows.

On 64 bit systems, for example, the maximum allowed value of a String is 2**63 – 1. We can see that Ruby will not allow us to allocate a string longer than that:

s = String.new(“1” * (2**63))

raises the exception:

RangeError: bignum too big to convert into `long’

However, while Ruby is capable of handling a String slightly shorter than the maximum, available memory is often a limiting factor:

s = String.new(“1” * (2**62))

raises the exception:

NoMemoryError: failed to allocate memory

LoadError

This exception is raised when a file required fails to load:

require ‘these/are/not/the/scripts/youre/looking/for’

raises the exception:

LoadError: no such file to load — these/are/not/the/scripts/youre/looking/for

A common pattern in Ruby is to rescue LoadError specifically (which is OK, since it’s not rescuing any other exceptions) to load an optional dependency which may not be present:

being

  require ‘rack’

rescue LoadError

  puts “Rack is not present, but it’s OK because we expected it”

end

Because of this, if your Ruby application is crashing due to a missing constant belonging to a file which has been required, it’s possible that the LoadError is being rescued improperly.

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector