user531065
user531065

Reputation: 763

Which system signal is sent to a ruby program when an exception is raised and the program stops execution?

Any time my program stops execution (either when shut down by cmd-c or when it encounters an exception), I want to take a few actions to shut down properly.

When I do cmd-c, I receive the signal TERM. What signal is sent when the program encounters an exception that is raised? How do I trap this with Signal.trap(...)?

Upvotes: 3

Views: 413

Answers (5)

Samwhoo
Samwhoo

Reputation: 312

As an alternative to the above solutions, you could look into the at_exit method.

Upvotes: 1

Patrick Oscity
Patrick Oscity

Reputation: 54674

The point wit exceptions is not trapping the signal via Signal.trap but rather wrapping the code that may raise an exception in a begin-rescue-end block. You have more Options though:

begin
  # here goes the code that may raise an exception
rescue ThisError
  # this code is executed when 'ThisError' was raised
rescue ThatError, AnotherError
  # this code is executed when 'ThatError' or 'AnotherError' was raised
rescue
  # this code is executed when any other StandardError was raised
else
  # this code is executed when NO exception was raised
ensure
  # this code is always executed
end

Here are some bit more practical examples of how to use this:

def compute_something(x,y)
  raise ArgumentError, 'x must not be lower than 0' if x < 0
  x/y + y
end

begin
  compute_something(-10,5)
rescue ArgumentError
  puts "some argument is erroneous!"
end

puts "---"

x=100
y=0

begin
  compute_something(x,y)
rescue ZeroDivisionError
  puts "division by zero! trying to fix that..."
  y=1
  retry
else
  puts "everything fine!"
end

puts "---"

begin
  compute_something(1)
rescue => e
  puts "the following error occured:"
  puts e
end

puts "---"

begin
  exit
ensure
  puts "i am always called!"
end

this outputs:

some argument is erroneous!
---
division by zero! trying to fix that...
everything fine!
---
the following error occured:
wrong number of arguments (1 for 2)
---
i am always called!

Upvotes: 1

Alberto Moriconi
Alberto Moriconi

Reputation: 1655

You can't catch the exception as a signal, but you can do something when it's raised using the 'EXIT' signal:

Signal.trap('EXIT') do
  puts "Terminating..."
  shutdown()
end

However, I just stated that you can do this; you really should use begin and rescue.

Upvotes: 1

Mark Reed
Mark Reed

Reputation: 95242

An exception is not a signal. The Ruby interpreter handles exceptions all in user code; there's nothing to trap.

If you want to handle exceptions, you need to do so in a rescue block.

Upvotes: 2

steenslag
steenslag

Reputation: 80065

You could wrap your code in a begin-ensure-end block. It would catch exceptions and CTRL-C. (You could add a rescue clause before the ensure).

begin
  sleep 10 #try CTRL-C here
  raise "kaboom" #RuntimeError
ensure
  puts "This must be printed no matter what."
end

Upvotes: 2

Related Questions