custom exceptions

Discussion in 'Ruby' started by Joe Van Dyk, Aug 30, 2005.

  1. Joe Van Dyk

    Joe Van Dyk Guest

    Hi,

    When should you define your own exceptions? Any rules of thumb?

    I'm writing an application that runs on a computer and listens for
    requests to start, kill, and view log files for other applications on
    that computer. Say I get a request to start an application on that
    computer and the requested executable doesn't exist. Should I throw a
    custom exception then? Or, say an application dies unexpectedly.=20
    What should I use for an exception then?

    Thanks,
    Joe
    Joe Van Dyk, Aug 30, 2005
    #1
    1. Advertising

  2. Joe Van Dyk

    Joe Van Dyk Guest

    On 8/30/05, Joe Van Dyk <> wrote:
    > Hi,
    >=20
    > When should you define your own exceptions? Any rules of thumb?
    >=20
    > I'm writing an application that runs on a computer and listens for
    > requests to start, kill, and view log files for other applications on
    > that computer. Say I get a request to start an application on that
    > computer and the requested executable doesn't exist. Should I throw a
    > custom exception then? Or, say an application dies unexpectedly.
    > What should I use for an exception then?


    The start function follows:

    class Application
    ...
    def start
    raise "No executable given!" if not @executable
    if @pid =3D fork
    Process.detach @pid
    @status =3D :running
    else
    @options.each do |option_name, option_value|
    ENV[option_name] =3D option_value
    end
    args =3D @arguments.join " "=20
    exec "#{ basedir }/#{ version }/#{ executable } #{ args }"
    end
    end
    ...
    end

    So, if there's no valid executable, then the exec call will fail.=20
    What's the best way of transmitting that information to the rest of
    the system?
    Joe Van Dyk, Aug 30, 2005
    #2
    1. Advertising

  3. Joe Van Dyk

    Eric Hodel Guest

    On 30 Aug 2005, at 10:52, Joe Van Dyk wrote:

    > When should you define your own exceptions? Any rules of thumb?


    I define custom exceptions when I need to differentiate them from the
    built-in exceptions.

    > I'm writing an application that runs on a computer and listens for
    > requests to start, kill, and view log files for other applications on
    > that computer. Say I get a request to start an application on that
    > computer and the requested executable doesn't exist. Should I throw a
    > custom exception then? Or, say an application dies unexpectedly.
    > What should I use for an exception then?


    Sometimes an exception with a message is enough. Other times I need
    to know the difference between two RuntimeErrors with different
    messages.

    I create my own exceptions for the second case because rescue
    FooError is easier than reading exception messages.

    --
    Eric Hodel - - http://segment7.net
    FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04
    Eric Hodel, Aug 30, 2005
    #3
  4. Joe Van Dyk

    Joe Van Dyk Guest

    On 8/30/05, Joe Van Dyk <> wrote:
    > On 8/30/05, Joe Van Dyk <> wrote:
    > > Hi,
    > >
    > > When should you define your own exceptions? Any rules of thumb?
    > >
    > > I'm writing an application that runs on a computer and listens for
    > > requests to start, kill, and view log files for other applications on
    > > that computer. Say I get a request to start an application on that
    > > computer and the requested executable doesn't exist. Should I throw a
    > > custom exception then? Or, say an application dies unexpectedly.
    > > What should I use for an exception then?

    >=20
    > The start function follows:
    >=20
    > class Application
    > ...
    > def start
    > raise "No executable given!" if not @executable
    > if @pid =3D fork
    > Process.detach @pid
    > @status =3D :running
    > else
    > @options.each do |option_name, option_value|
    > ENV[option_name] =3D option_value
    > end
    > args =3D @arguments.join " "
    > exec "#{ basedir }/#{ version }/#{ executable } #{ args }"
    > end
    > end
    > ...
    > end
    >=20
    > So, if there's no valid executable, then the exec call will fail.
    > What's the best way of transmitting that information to the rest of
    > the system?


    Eeek. So, I was trying to do a test like:

    def test_start_bad_application
    a =3D Application.new invalid_application_executable
    assert_raise(RuntimeError) { a.start }
    assert !a.running?
    assert_equal :failed, a.status
    end

    But since it forks into a new process, I don't catch the exception. I
    could check to see if the executable exists (and is executable) before
    going into the fork, and if it's not valid, throw an exception. Is
    that my best bet?
    Joe Van Dyk, Aug 30, 2005
    #4
  5. Joe Van Dyk wrote:
    > On 8/30/05, Joe Van Dyk <> wrote:
    >> On 8/30/05, Joe Van Dyk <> wrote:
    >>> Hi,
    >>>
    >>> When should you define your own exceptions? Any rules of thumb?
    >>>
    >>> I'm writing an application that runs on a computer and listens for
    >>> requests to start, kill, and view log files for other applications
    >>> on that computer. Say I get a request to start an application on
    >>> that computer and the requested executable doesn't exist. Should I
    >>> throw a custom exception then? Or, say an application dies
    >>> unexpectedly. What should I use for an exception then?


    I'd go with Eric's rule of thumb. It's not an exact science but you there
    is a minimal criterium: if you need to catch this exception separately
    from others you should introduce a new exception type.

    Btw, here's a nice short script to print a class hierarchy of all
    exceptions:

    require 'pp'
    tree = (cr = lambda {|h,k| h[k] = Hash.new &cr})[{},nil]
    ObjectSpace.each_object(Class) {|cl| if cl.ancestors.include? Exception
    then cl.ancestors.reverse.inject(tree){|tr,cl| tr[cl]} end}
    pp tree


    >> The start function follows:
    >>
    >> class Application
    >> ...
    >> def start
    >> raise "No executable given!" if not @executable
    >> if @pid = fork
    >> Process.detach @pid
    >> @status = :running
    >> else
    >> @options.each do |option_name, option_value|
    >> ENV[option_name] = option_value
    >> end
    >> args = @arguments.join " "
    >> exec "#{ basedir }/#{ version }/#{ executable } #{ args }"
    >> end
    >> end
    >> ...
    >> end
    >>
    >> So, if there's no valid executable, then the exec call will fail.
    >> What's the best way of transmitting that information to the rest of
    >> the system?

    >
    > Eeek. So, I was trying to do a test like:
    >
    > def test_start_bad_application
    > a = Application.new invalid_application_executable
    > assert_raise(RuntimeError) { a.start }
    > assert !a.running?
    > assert_equal :failed, a.status
    > end
    >
    > But since it forks into a new process, I don't catch the exception. I
    > could check to see if the executable exists (and is executable) before
    > going into the fork, and if it's not valid, throw an exception. Is
    > that my best bet?


    I guess so.

    Kind regards

    robert
    Robert Klemme, Aug 31, 2005
    #5
  6. Joe Van Dyk

    Joe Van Dyk Guest

    On 8/30/05, Eric Hodel <> wrote:
    > On 30 Aug 2005, at 10:52, Joe Van Dyk wrote:
    >=20
    > > When should you define your own exceptions? Any rules of thumb?

    >=20
    > I define custom exceptions when I need to differentiate them from the
    > built-in exceptions.
    >=20
    > > I'm writing an application that runs on a computer and listens for
    > > requests to start, kill, and view log files for other applications on
    > > that computer. Say I get a request to start an application on that
    > > computer and the requested executable doesn't exist. Should I throw a
    > > custom exception then? Or, say an application dies unexpectedly.
    > > What should I use for an exception then?

    >=20
    > Sometimes an exception with a message is enough. Other times I need
    > to know the difference between two RuntimeErrors with different
    > messages.
    >=20
    > I create my own exceptions for the second case because rescue
    > FooError is easier than reading exception messages.


    Should the custom exception be in its own class? Or in a module?

    Say I have the following class

    class NodeManager
    def start_application args
    end
    end=20

    There are a few different ways start_application could fail:
    - bad arguments
    - user attempted to start the same application twice (which is an
    error for us)
    - not enough resources available

    I want to distinguish between those different reasons. So, would I
    want to have something like this:

    module JoesExceptions # figure out some name
    class BadArgumentsForApplication < Exception
    end

    class ApplicationStartedTwice < Exception
    end

    class NotEnoughResourcesForApplication < Exception
    end
    end

    And then, in start_application:

    def start_application args
    # if arguments are bad
    raise BadArgumentsForApplication
    # and so on
    end
    Joe Van Dyk, Sep 1, 2005
    #6
  7. Joe Van Dyk

    Joe Van Dyk Guest

    On 9/1/05, Joe Van Dyk <> wrote:
    > On 8/30/05, Eric Hodel <> wrote:
    > > On 30 Aug 2005, at 10:52, Joe Van Dyk wrote:
    > >
    > > > When should you define your own exceptions? Any rules of thumb?

    > >
    > > I define custom exceptions when I need to differentiate them from the
    > > built-in exceptions.
    > >
    > > > I'm writing an application that runs on a computer and listens for
    > > > requests to start, kill, and view log files for other applications on
    > > > that computer. Say I get a request to start an application on that
    > > > computer and the requested executable doesn't exist. Should I throw =

    a
    > > > custom exception then? Or, say an application dies unexpectedly.
    > > > What should I use for an exception then?

    > >
    > > Sometimes an exception with a message is enough. Other times I need
    > > to know the difference between two RuntimeErrors with different
    > > messages.
    > >
    > > I create my own exceptions for the second case because rescue
    > > FooError is easier than reading exception messages.

    >=20
    > Should the custom exception be in its own class? Or in a module?
    >=20
    > Say I have the following class
    >=20
    > class NodeManager
    > def start_application args
    > end
    > end
    >=20
    > There are a few different ways start_application could fail:
    > - bad arguments
    > - user attempted to start the same application twice (which is an
    > error for us)
    > - not enough resources available
    >=20
    > I want to distinguish between those different reasons. So, would I
    > want to have something like this:
    >=20
    > module JoesExceptions # figure out some name
    > class BadArgumentsForApplication < Exception
    > end
    >=20
    > class ApplicationStartedTwice < Exception
    > end
    >=20
    > class NotEnoughResourcesForApplication < Exception
    > end
    > end
    >=20
    > And then, in start_application:
    >=20
    > def start_application args
    > # if arguments are bad
    > raise BadArgumentsForApplication


    I guess that would be:
    raise JoesApplication::BadArgumentsForApplication

    > # and so on
    > end
    >
    Joe Van Dyk, Sep 1, 2005
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris Dunaway

    Custom Exceptions with Web Services

    Chris Dunaway, Jan 13, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    408
    Shiv Kumar
    Jan 13, 2004
  2. Ahmed Moustafa
    Replies:
    5
    Views:
    30,009
    Chris Smith
    Jul 14, 2004
  3. Paul Miller
    Replies:
    3
    Views:
    1,014
    Alex Martelli
    Nov 12, 2003
  4. Replies:
    3
    Views:
    607
    Sherm Pendley
    Apr 16, 2007
  5. Lie
    Replies:
    3
    Views:
    611
Loading...

Share This Page