Where should exception message logic be put?

T

Tom Ewall

Given the need for a method to handle the message for a given
exception, where should that logic be placed? (that is, the logic for
the creation of the message is non-trival, depending on, for the
example I'm giving here, on the String "parm" which is passed in) One
solution would be to put it in the exception class itself, as a static
method. Another solution would be to put it somewhere else, like some
sort of utility class. To make clear my question, here are a couple
of examples:

1) throw new MyException( MyException.getMessageForMyException( parm )
);
2) throw new MyException( UtilityClass.getMessageForMyException( parm
) );

My inclination would be to not put the getMessageForMyException( )
method in the exception class itself (i.e. MyException), however when
asked about why not, I couldn't give a good reason.
 
I

iamfractal

Given the need for a method to handle the message for a given
exception, where should that logic be placed? (that is, the logic for
the creation of the message is non-trival, depending on, for the
example I'm giving here, on the String "parm" which is passed in) One
solution would be to put it in the exception class itself, as a static
method. Another solution would be to put it somewhere else, like some
sort of utility class. To make clear my question, here are a couple
of examples:

1) throw new MyException( MyException.getMessageForMyException( parm )
);
2) throw new MyException( UtilityClass.getMessageForMyException( parm
) );

Hi!

Do remember that exceptions are classes just like any other and that
they may express arbitrarily complicated functionality. True, most
people use them as glorified (throwable) Strings, but this is a narrow
view which, if held, can blind you to appropriate, object-oriented
solutions.

Exceptions, for example, are the ideal places to hold the actions that
should be taken in certain, problematic situations; indeed, they can
be seen as the ideal and only entry-point into a somehow corrupted
environment. So instead of the usual idiom of the following code:

private void doSomething(BlackBox box) {
try {
box.prepare();
box.fiddle();
} catch (FiddlingException e) {
Logger.log("Something failed: " + e);
box.cleanUpAfterFiddle();
} catch (PreparationException e) {
Logger.log("Something failed: " + e);
box.cleanUpAfterPreparation();
}
}

It's often better to encapsulte the cleaning up in the exception
created as a result of the problem itself:

private void doSomething(BlackBox box) {
try {
box.prepare();
box.fiddle();
} catch (BoxException e) {
Logger.log("Something failed: " + e);
e.cleanUp();
}
}


And to get back to your question: given all the above, your number 2
is the least desirable of the choices, because it is an encapsulation
violation: the data relevant for MyException is controlled by
UtilityClass, but there's no need for the data relevant for
MyException to be controlled by any class other than MyException
itself.

Your number 1 choice is more desirable, though still smacks of
thinking of Exceptions as poor cousins to normal classes. It's good
because it allows MyException to create its own message based on a
parameter (which is perfect encapsulation), but the static method is
unnecessary (and unextensible).

Better is to simple pass the parm in as a string to the constructor
and let MyException privately create the appropriate message itself
(the constructor essentially becomes a parameterized factory method,
which means your solution has taken a step closer to GoF's Design
Patterns, which means that you've demonstrably improved matters):

throw new MyException(parm);

Lovely.

My inclination would be to not put the getMessageForMyException( )
method in the exception class itself (i.e. MyException), however when
asked about why not, I couldn't give a good reason.

As you can see, my inclination is the opposite.

..ed

www.EdmundKirwan.com - Home of The Fractal Class Composition
 
T

Tom Ewall

Thank your for your response. Sorry to not reply sooner.

I like the general thought of your answer very much. The problem with
throw new MyException(parm) is that one expects a constructor with
this signature will be using the parm as the message. That is, the
general practice of exceptions is that in the call new
constructor(String something), something will be a message.
 
R

Roedy Green

Your premise is that the low levl code does know what to do. That
smells like a bad design to me.

I find generally that as a newbie I tried to catch and deal with every
exception on the very line it occurred. Later I discovered code is
much more reusable if you just pass the exceptions on up.

Basically, you handle them as soon as you can, thinking in terms of
the code being reused.

Instead of dumping out an error message, package the information into
the exception.

Then the caller can decide what to do with it. He can restate the
problem in terms suitable for his audience.
 
H

Hugh Beyer

(e-mail address removed) (Tom Ewall) wrote in
Thank your for your response. Sorry to not reply sooner.

I like the general thought of your answer very much. The problem with
throw new MyException(parm) is that one expects a constructor with
this signature will be using the parm as the message. That is, the
general practice of exceptions is that in the call new
constructor(String something), something will be a message.

Is this really the most natural signature for your situation? Your
exception most appropriately takes a single string to get all the context
it needs?

This really is the best solution.
(e-mail address removed) wrote in message

Only if the cleanUp() is not dependent of the context in doSomething. It
shouldn't clean up state doSomething() is managing.

Hugh
 
D

Dale King

Hello, (e-mail address removed)!
You said:
(e-mail address removed) (Tom Ewall) wrote in message

Hi!

Do remember that exceptions are classes just like any other and that
they may express arbitrarily complicated functionality. True, most
people use them as glorified (throwable) Strings, but this is a narrow
view which, if held, can blind you to appropriate, object-oriented
solutions.

Exceptions, for example, are the ideal places to hold the actions that
should be taken in certain, problematic situations; indeed, they can
be seen as the ideal and only entry-point into a somehow corrupted
environment. So instead of the usual idiom of the following code:

private void doSomething(BlackBox box) {
try {
box.prepare();
box.fiddle();
} catch (FiddlingException e) {
Logger.log("Something failed: " + e);
box.cleanUpAfterFiddle();
} catch (PreparationException e) {
Logger.log("Something failed: " + e);
box.cleanUpAfterPreparation();
}
}

It's often better to encapsulte the cleaning up in the exception
created as a result of the problem itself:

private void doSomething(BlackBox box) {
try {
box.prepare();
box.fiddle();
} catch (BoxException e) {
Logger.log("Something failed: " + e);
e.cleanUp();
}
}

That makes very little sense to me except in the very rarest of
circumstances. The pemise of exceptions is that something
unexpected happened and you throw an exception because the code
where the exception occurs has no idea what to do about it and
you hope someone catches it that knows what to do.

Your premise is that the low levl code does know what to do. That
smells like a bad design to me.

It is true at exceptions could include more information such as a
reference to an offendin item, but I can't think of too many
cases where any more infomation was needed than just that an
exception occured. Perhaps for debug messages, but then you can
do that in the text string.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top