# Help me design my exception classes

**URL:** <https://rubytalk.org/t/help-me-design-my-exception-classes/33251>\
**Category:** ruby-talk\
**Created:** [28 November 2006 01:07 UTC](https://rubytalk.org/t/help-me-design-my-exception-classes/33251 "2006-11-28T01:07:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![J\_B\_Rainsberger](https://avatars.discourse-cdn.com/v4/letter/j/b5e925/32.png) [@J\_B\_Rainsberger](https://rubytalk.org/u/J_B_Rainsberger)\
**Post date:** [28 November 2006 01:07 UTC](https://rubytalk.org/t/help-me-design-my-exception-classes/33251/1 "2006-11-28T01:07:09Z")

</div>

Everyone:

Being a Java programmer learning Ruby, I don't want my Java-based prejudices about design pollute my thinking as I make the transition to being a fluent Ruby speaker. Accordingly, I'd like you to suggest to me how I should design my exception classes.

I Googled around for about 10 minutes, but couldn't find anything on point, and I found it difficult to rummage through everything. If someone has written extensively about this already, please just point me there.

My concrete example is this: I'm "spooling" documents to be printed by sending them via FTP. There might be other ways to spool documents, such as by sending them via e-mail, to a printer, to the screen. I would like to represent an exception that occurs in the underlying transport mechanism (FTP, SMTP, printing subsystem...), but of course, I don't want my clients to know about those things directly.

In Java, I would do something like

//...  
catch (FTPException wrapped) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new RuntimeException("Unable to spool document", wrapped);  
}

where the FTP library would throw me an FTPException to indicate that something went wrong. I only throw a RuntimeException because I don't necessarily want to create a custom exception class when I only report generic, unrecoverable "I couldn't spool" exceptions. At that point, there's nothing (yet) to gain from distinguishing exceptions by their type.

What's the corresponding exception class in Ruby to Java's generic RuntimeException. Is it RuntimeError? StandardError? Exception? Does anyone want to tell me I'm nuts and show me a more "standard" way of designing exceptions in Ruby?

Thanks.

> **···**
>
> --  
> J. B. (Joe) Rainsberger :: [http://www.jbrains.ca](http://www.jbrains.ca)  
> Your guide to software craftsmanship  
> JUnit Recipes: Practical Methods for Programmer Testing  
> 2005 Gordon Pask Award for contribution Agile Software Practice

---

<div class="post-metadata">

**Author:** ![Tom\_Copeland](https://avatars.discourse-cdn.com/v4/letter/t/94ad74/32.png) [@Tom\_Copeland](https://rubytalk.org/u/Tom_Copeland)\
**Post date:** [28 November 2006 02:08 UTC](https://rubytalk.org/t/help-me-design-my-exception-classes/33251/2 "2006-11-28T02:08:58Z")

</div>

> Being a Java programmer learning Ruby,

Welcome! Your JUnit book rocks.

> What's the corresponding exception class in Ruby to Java's generic  
> RuntimeException. Is it RuntimeError? StandardError? Exception? Does  
> anyone want to tell me I'm nuts and show me a more "standard" way of  
> designing exceptions in Ruby?

I usually rescue a generic Exception:

> **···**
>
> On Tue, 2006-11-28 at 10:07 +0900, J. B. Rainsberger wrote:
> 
> # =========== $ irb irb(main):001:0\> begin irb(main):002:1\* raise "hey" irb(main):003:1\> rescue Exception =\> e irb(main):004:1\> puts e.class irb(main):005:1\> end RuntimeError =\> nil
> 
> You can create your own exceptions, of course:
> 
> # =========== irb(main):006:0\> class MyException \< Exception irb(main):007:1\> def initialize ; puts "hello" ; super ; end irb(main):008:1\> end =\> nil irb(main):009:0\> MyException.new hello =\> #\<MyException: MyException\>
> 
> Yours,
> 
> Tom

---

<div class="post-metadata">

**Author:** ![Jacob\_Fugal](https://avatars.discourse-cdn.com/v4/letter/j/439d5e/32.png) [@Jacob\_Fugal](https://rubytalk.org/u/Jacob_Fugal)\
**Post date:** [28 November 2006 15:01 UTC](https://rubytalk.org/t/help-me-design-my-exception-classes/33251/3 "2006-11-28T15:01:06Z")

</div>

You're on the right track. I'd use the same model you've got going in  
your Java design. For a usage like this, RuntimeError is the one  
you're looking for. Fortunately, Ruby uses RuntimeError as the default  
when you just raise a string instead of a specific Exception object.

Also, in Ruby to raise specific exceptions you don't need to call new  
on the specific exception class, just provide more arguments to raise.  
And unless you do your own custom wrapping in a subclass, you can't  
wrap a previous exception -- but you can subsume the backtrace as an  
additional parameter to raise. Unfortunately, you need to specify the  
exception class as the first parameter when you do so.

So your syntax could look like this:

&nbsp;&nbsp;begin  
&nbsp;&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;&nbsp;# code that might raise FTPException  
&nbsp;&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;rescue FTPException =\> wrapped  
&nbsp;&nbsp;&nbsp;&nbsp;raise RuntimeError, "Unable to spool document", wrapped.backtrace  
&nbsp;&nbsp;end

Alternately, if you decide you do want to create your own class of  
exception for later discernment, you will inherit from RuntimeError:

&nbsp;&nbsp;class SpoolError \< RuntimeError; end

&nbsp;&nbsp;begin  
&nbsp;&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;rescue FTPException =\> wrapped  
&nbsp;&nbsp;&nbsp;&nbsp;raise SpoolError, "Unable to spool document", wrapped.backtrace  
&nbsp;&nbsp;end

Jacob Fugal

> **···**
>
> On 11/27/06, J. B. Rainsberger \<jbrains762@gmail.com\> wrote:
> 
> > My concrete example is this: I'm "spooling" documents to be printed by  
> > sending them via FTP. There might be other ways to spool documents, such  
> > as by sending them via e-mail, to a printer, to the screen. I would like  
> > to represent an exception that occurs in the underlying transport  
> > mechanism (FTP, SMTP, printing subsystem...), but of course, I don't  
> > want my clients to know about those things directly.
> > 
> > In Java, I would do something like
> > 
> > //...  
> > catch (FTPException wrapped) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new RuntimeException("Unable to spool document", wrapped);  
> > }
> > 
> > where the FTP library would throw me an FTPException to indicate that  
> > something went wrong. I only throw a RuntimeException because I don't  
> > necessarily want to create a custom exception class when I only report  
> > generic, unrecoverable "I couldn't spool" exceptions. At that point,  
> > there's nothing (yet) to gain from distinguishing exceptions by their type.
> > 
> > What's the corresponding exception class in Ruby to Java's generic  
> > RuntimeException. Is it RuntimeError? StandardError? Exception?

---

<div class="post-metadata">

**Author:** ![Joel\_VanderWerf1](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@Joel\_VanderWerf1](https://rubytalk.org/u/Joel_VanderWerf1)\
**Post date:** [28 November 2006 06:41 UTC](https://rubytalk.org/t/help-me-design-my-exception-classes/33251/4 "2006-11-28T06:41:29Z")

</div>

Tom Copeland wrote:

> > Being a Java programmer learning Ruby,
> 
> Welcome! Your JUnit book rocks.
> 
> > What's the corresponding exception class in Ruby to Java's generic RuntimeException. Is it RuntimeError? StandardError? Exception? Does anyone want to tell me I'm nuts and show me a more "standard" way of designing exceptions in Ruby?
> 
> I usually rescue a generic Exception:
> 
> # =========== $ irb irb(main):001:0\> begin irb(main):002:1\* raise "hey" irb(main):003:1\> rescue Exception =\> e irb(main):004:1\> puts e.class irb(main):005:1\> end RuntimeError =\> nil

Careful... that's a wide net to cast. It will catch Interrupt and SystemExit, for example. StandardError is often (but not always) the right generic class to catch.

Note that the syntax

rescue =\> e

(with exception class omitted) is the same as

rescue StandardError =\> e

This suggests that StandardError was intended to be thought of as "generic".

> **···**
>
> > On Tue, 2006-11-28 at 10:07 +0900, J. B. Rainsberger wrote:
> 
> --  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

---

<div class="post-metadata">

**Author:** ![Tom\_Copeland](https://avatars.discourse-cdn.com/v4/letter/t/94ad74/32.png) [@Tom\_Copeland](https://rubytalk.org/u/Tom_Copeland)\
**Post date:** [28 November 2006 07:17 UTC](https://rubytalk.org/t/help-me-design-my-exception-classes/33251/5 "2006-11-28T07:17:25Z")

</div>

Hm, good point, StandardError probably is a better way to go. I've  
always used Exception, but I think I'll go back and revisit some of  
those usages now 🙂

Yours,

Tom

> **···**
>
> On Tue, 2006-11-28 at 15:41 +0900, Joel VanderWerf wrote:
> 
> > Careful... that's a wide net to cast. It will catch Interrupt and  
> > SystemExit, for example. StandardError is often (but not always) the  
> > right generic class to catch.
> > 
> > Note that the syntax
> > 
> > rescue =\> e
> > 
> > (with exception class omitted) is the same as
> > 
> > rescue StandardError =\> e
> > 
> > This suggests that StandardError was intended to be thought of as "generic".

---

<div class="post-metadata">

**Author:** ![Jeremy\_Henty](https://avatars.discourse-cdn.com/v4/letter/j/c6cbf5/32.png) [@Jeremy\_Henty](https://rubytalk.org/u/Jeremy_Henty)\
**Post date:** [28 November 2006 08:30 UTC](https://rubytalk.org/t/help-me-design-my-exception-classes/33251/6 "2006-11-28T08:30:21Z")

</div>

DRb does this:

&nbsp;&nbsp;&nbsp;&nbsp;class DRbError \< RuntimeError; end

and uses DRbError as a superclass of all DRb error classes. Is this a  
standard convention for Ruby libraries?

Jeremy Henty
