ruby picture

RCR 175: Provide Ruby interface to error_print()

Submitted by Paul Brannan (Thu Dec 18 10:12:30 UTC 2003)

Abstract

The interpreter should provide an interface to error_print() so that users can log exceptions in the same format as Ruby. This interface should be available via the function Exception#format().

Problem

Ruby prints out exceptions in a very specific format; it does this with a function in eval.c called error_print(). Users often want to print exceptions either to the screen or to a networked logger; for consistency with Ruby, it would be nice to print these exceptions in the same format as Ruby does.

 Currently the only way to print exceptions in this format is like this: <pre> str = ''
 first = true
 $!.backtrace.each do |bt|
   str << (first ? "#{bt}: #{exc.message} (#{exc.class}) " : "    from #{bt} ")
   first = false
 end
 puts str
 </pre> 
 (which is similar to what irb does), or via tricks/hacks using threads or fork().  There should be a simple interface to this feature.

Proposal

The following changes should be made:
 <ol> <li>A new C function should be added which either returns a String containing the formatted exception message or prints the formatted exception message to stderr, depending on a flag that is passed to the function.  This function can be called error_format().</li>
 <li>error_print() should be rewritten to call error_format().  It should always tell error_format() to print to stderr, because it is unwise to create objects in the presence of certain exceptions (e.g. MemoryError).</li>
 <li>The Exception class should get a new function called Exception#format() which formats the exception using error_format() and returns the result as a String.</li>
 <li>IRB should be changed to use Exception#format() to print exceptions instead of iterating over the backtrace.</li>
 </ol> 
 For example: <pre> def foo
   raise 'foo!'
 end begin
   foo
 rescue
   puts $!.format #=> test.rb:10:in `foo': foo! (RuntimeError)
                  #           from test.rb:14
 end
 </pre> 

Analysis

Exception#format() is a much cleaner interface than the hack shown earlier, and is not difficult to implement. It would also simplify network loggers, IRB, and IRB-like programs.

Implementation

The following is an implementation in pure Ruby so that users can experiment with it; the actual implementation of this RCR should be written in C.

    
 class Exception
  def format
    str = ''
    first = true
    self.backtrace.each do |bt|
      str << (first ? "#{bt}: #{self.message} (#{self.class})" : "        from #{bt}")
      first = false
    end
    return str
  end
end
ruby picture
Comments Current voting

I've got a few "def print_exception" in the scripts I've written. Definitely useful. -matt


Strongly opposed 0
Opposed 0
Neutral 0
In favor 15
Strongly advocate 6
ruby picture
If you have registered at RCRchive, you may now sign in below. If you have not registered, you may sign up for a username and password. Registering enables you to submit new RCRs, and vote and leave comments on existing RCRs.
Your username:
Your password:

ruby picture

Powered by .