Exception handling

A

Andre Rothe

Hello!

I try to find some information about a best-practice exception
framework. Maybe this group can help me.

An application throws an exception within a low-level method, let us
say, within a database access layer. It has occured as reaction of a
wrong value given by the user. The method can throw the exception, the
next higher abstraction layer can rollback the associated database
operation and throw it up to the client application.

To code that, I can use a generalized exception class like
IllegalArgumentException, but also a detailled exception class like
WrongBirthdayException. If I use the first one, the client cannot give
a specific message to the user (because the method stores several
values and only one was wrong).

If I try the detailled exception I can use exception chaining or
translation to hide the low-level exception from the client. To achive
that, I could define a high-level exception within the interface of
the service, maybe ServiceException, which is a superclass of
WrongBirthdayException.

public void storeSomething() throws ServiceException;

But now I don't have enough information within the client application
to present a detailled message to the user. I know, there were a
ServiceException, but I have to use

a) instanceof to find the real sub-class or
b) getCause() to find the reason for the exception

If I specifiy the detailled exception WrongBirthdayException within
the service interface, I will have the correct reason for the
exception:

public void storeSomething() throws WrongBirthdayException;

try {
service.storeSomething();
} catch (WrongBirthdayException e) {
// do something
}

But such a service method can throw several exceptions (one for every
possible problem). So I would have a lot of possible exception classes
within the interface definition and a lot of several catch statements
within the client. Both will bloat my code.

public void storeSomething() throws
WrongBirthdayException,WrongNameException,WrongPostcodeException;

On the other hand I could use the generalized exception:

try {
service.storeSomething();
} catch (ServiceException e) {
handleIt(e);
}

private void handleIt(ServiceException e) {
if (e instanceof WrongBirthdayException) {

}
if (e instanceof WrongPostcodeException) {

}
// ...
}

but now I have to use a) or b) (see above) to find and to react on the
exception. Another possibility is to use the generalized exception to
reduce the code overhead within the interface but I could use the
detailled exception on the catch statement:

public void storeSomething() throws ServiceException {
throw new WrongBirthdayException();
}

try {
service.storeSomething();
} catch (WrongBirthdayException e) {

} catch (ServiceException e) {

}

But here I will get stomach ache, I use information about detailled
exception, which I don't get from the service interface definition.

A further method could be the definition of a detailled message string
direct within the service as part of a generalized exception class.
But there are two disadvantages: 1) the service can run with another
locale settings than the client; 2) sometimes you need programatic
access to the exception reason instead of simple logging/displaying
the message to change the code path.

Are there any best-practice solutions (patterns?) for this problem? I
would be happy about some links to examples or discussions.

Thanks a lot
Andre
 
M

markspace

Andre said:
A further method could be the definition of a detailled message string


This one is definitely not best practice. Avoid it at all costs.

Are there any best-practice solutions (patterns?) for this problem? I
would be happy about some links to examples or discussions.


I can't say I know best practice here, but some ideas do occur to me.


Don't forget that Java exception are just regular classes. Any time you
see a construct, for any class, like this:

if( object instanceof ClassA ) {
do something ...
} else if( object instanceof ClassB ) {
do something else...
} ... etc., lots more....

You should think polymorphism and overriding.

public interface ExceptionHandler {
void handler();
}

public abstract class DBFrameworkException
extends Exception
implements ExceptionHandler
{
ExceptionHandler handler;
void setHandler( ExceptionHandler h) {
handler = h;
}
@Override
void handler() {
if( handler != null ) {
handler.handler();
}
}
}

public class DataTypeMismatch extends DBFrameworkException
{
}

Now at least you don't have to check for lots of different classes. If
the class is "ExceptionHandler" you can just execute the handler
method... which might do different things based on the handler that was
installed.

Since the handler can be set, you can make a factory or registry of
handlers, and inject the behavior into the lower layers. No need to
specify at compile time or hard code it, just look for the handler and
install one if it exists. If none exist, maybe an default handler that
just writes to the logger would be appropriate.

This allows you to use fewer classes--you only need one exception class,
really. And you only need as many handlers as you have different
behaviors. No more than you'd have to write in your big ol' if-else
stack you had.
 
J

Jean-Baptiste Nizet

Andre Rothe a écrit :
public void storeSomething() throws WrongBirthdayException;

try {
service.storeSomething();
} catch (WrongBirthdayException e) {
// do something
}

But such a service method can throw several exceptions (one for every
possible problem). So I would have a lot of possible exception classes
within the interface definition and a lot of several catch statements
within the client. Both will bloat my code.

User input validation should be performed before the call to
service.storeSomething(). Of course, you should program storeSomething
in a defensive way, and verify in the service method that its contract
is fulfilled by the caller, but then an IllegalArgumentException will do
fine.

In pseudo-code, instead of doing
1. accept input from the user
2. call the service
3. catch an exception from the service
4. display errors to the user

you should do

1. accept input from the user
2. validate the input
3. display errors to the user if any
4. if no error, call the service
5. if the service throws an exception, then your validation logic at
step 2 has a bug.

If the service is the only component being able to perform the
validation logic for any reason (for example, the validation logic
depends on values fetched or computed in the service method itself),
then you might use a rich ValidationException, containing, for example,
a list of validation errors. Each validation error would contain a
message key and some arguments of the error message, which would be
displayed in an internationalized way by the presentation layer.

JB.
 
A

Andre Rothe

Hello!

It was only a simple example to construct the problem. Often I cannot
validate the user input on that way, it is possible to get input from
other applications or components, so it is your component, which has
to check the input on the deepest level. Your own component must not
be a database access, but it is on your turn to throw exceptions back
to the other unchangeable components of the system.

Thanks
Andre
 
A

Andre Rothe

This one is definitely not best practice.  Avoid it at all costs.

Yes, I have added it for completeness :)
Now at least you don't have to check for lots of different classes.  If
the class is "ExceptionHandler" you can just execute the handler
method... which might do different things based on the handler that was
installed.

Oh, I understand. I can use the exceptions of the service to build
another object instance within the client, which implements the
interface ExceptionHandler. This could be useful, I will think about
it.
Since the handler can be set, you can make a factory or registry of
handlers, and inject the behavior into the lower layers.  No need to
specify at compile time or hard code it, just look for the handler and
install one if it exists.  If none exist, maybe an default handler that
just writes to the logger would be appropriate.

This allows you to use fewer classes--you only need one exception class,
really.  And you only need as many handlers as you have different
behaviors.  No more than you'd have to write in your big ol' if-else
stack you had.

This would be nice, if I can integrate it into the system, I will try
it.
Client and service are not on the same machine, so it could be hard to
implement it, but this is a challange for me :)

Thanks
Andre
 
P

Pitch



These are my general rules:

- layer X catches everything but RuntimeExceptions and throws
"X_Exception"

- layer Y catches everything but RuntimeExceptions and throws
"Y_Exception"

- GUI/presentation/interface layer catches everything and logs it or
displays a dialog or whatever.

- exceptions to these rules exists and depend on the case, especially if
RuntimeExceptions are to be ignored or not


When I say layer X I mean the interface/methods of that layer.

Rules inside a layer of abstraction:

- If it has to do with possible error in my business logic it throws
MyException, else it bubbles up whatever happened

- If there are several modules in a leyer, each can have its own
"ModuleException" which extends "LayerException"


HTH
 
T

Tom Anderson

These are my general rules:

- layer X catches everything but RuntimeExceptions and throws
"X_Exception"

- layer Y catches everything but RuntimeExceptions and throws
"Y_Exception"

- GUI/presentation/interface layer catches everything and logs it or
displays a dialog or whatever.

This is pretty much the Right Way To Do It.

But note that in this case, you have to be careful about using
IllegalArgumentException, as it's a RuntimeException. If code in a deep
layer is doing input validation (say, taking a user-entered string and
looking something up in a database with it), then failure of validation
needs to be signalled with a checked layer-specific exception, otherwise
it will go through the upper layers and annoy the user.

On the other hand, if validation fails for a reason which could have been
caught by an upper layer (a parameter is null, an argument is too long or
the wrong colour, etc), then that's a programming error on the part of the
upper layer, and it's okay to throw an IllegalArgumentException. Although
it might still be wise to throw a checked exception.

tom
 
D

Daniel Pitts

Andre said:
Hello!

I try to find some information about a best-practice exception
framework. Maybe this group can help me.

An application throws an exception within a low-level method, let us
say, within a database access layer. It has occured as reaction of a
wrong value given by the user. The method can throw the exception, the
next higher abstraction layer can rollback the associated database
operation and throw it up to the client application.
This is a bad pattern.

The low-level methods should through exceptions which indicate
programmer error. Higher-level methods should validate *before* calling
lower-level methods. The high-level methods can either throw
appropriate exceptions or directly report problems to the user.

The reason I advocate this pattern is because Low-Level methods
shouldn't know or care whether their invocation is due to a user action,
or an automated process, or something else.

Low-Level methods should be designed to report programmer errors and
low-level interface problems (IO errors, DB errors, etc...)

Higher level methods should be task oriented (for example, "User
requested a record") The higher level method should verify that the
user entered valid data, and that the record was returned correctly.

It may seem like a little bit of repeating yourself, but once you
realize that the lower-level exception has a different purpose, you can
get over the fact that you might write the same check in two places.

To avoid the duplication of "checks", you can create a predicate method
somewhere that can be called by the lower-level method and the higher
level method. In the lower-level method, you can document in the
contract that the precondition is "isValidFoo()" (for example). This
makes it a programmer error to call a method with a bad precondition.

Now, if the lower-level method throws an exception, it can be of three
kinds: High-Level Programmer error (bug: failed to verify
precondition), Low-Level Programmer Error (bug: in the library),
Exceptional Circumstance (i.e. IOException). The first two should be
reported to the user only as "There was an internal error handling your
request", and the full stack-trace logged somewhere for reporting and
reproducing. The latter exception can be reported to the user with an
appropriate message (eg. "Unable to communicate with database", or
"Unable to open file")

Of course, this is all idealized. Sometimes it is infeasible to verify
user-input before calling the lower-level method. In which case, the
lower-level method can still throw a "low-level" exception, but it
should still be translated into "high-level" message by the higher level
code.

I hope this all makes sense. I could go on further, but if I go on any
longer and I'll have to break it into sections, gather references, add
markup, throw and catch exceptions, etc... ;-)
 
L

Lew

Tom said:
This is pretty much the Right Way To Do It.

But note that in this case, you have to be careful about using
IllegalArgumentException, as it's a RuntimeException. If code in a deep
layer is doing input validation (say, taking a user-entered string and
looking something up in a database with it), then failure of validation
needs to be signalled with a checked layer-specific exception, otherwise
it will go through the upper layers and annoy the user.

On the other hand, if validation fails for a reason which could have
been caught by an upper layer (a parameter is null, an argument is too
long or the wrong colour, etc), then that's a programming error on the
part of the upper layer, and it's okay to throw an
IllegalArgumentException. Although it might still be wise to throw a
checked exception.

tom's advice jibes with what I've read from the pundits, that unchecked
exceptions generally correspond to programmer error and checked exceptions to
environmental issues or other failures outside programmer control, such as a
dropped connection.
 
A

Arne Vajhøj

Daniel said:
This is a bad pattern.

The low-level methods should through exceptions which indicate
programmer error. Higher-level methods should validate *before* calling
lower-level methods.

That is not always possible.
Of course, this is all idealized. Sometimes it is infeasible to verify
user-input before calling the lower-level method. In which case, the
lower-level method can still throw a "low-level" exception, but it
should still be translated into "high-level" message by the higher level
code.

Yep.

Arne
 
R

Roedy Green

Are there any best-practice solutions (patterns?) for this problem? I
would be happy about some links to examples or discussions.

Don't catch an exception unless you can effectively neutralise it.
Otherwise, leave it for higher levels to deal with.

To make it easier for higher levels, it is sometimes a good thing to
catch a low level exception and rethrow a higher level
more-application specific one.
 
A

Andre Rothe

Hi,

I think, this will not work in every case. If you have a user
management system, which allows the user to change his password
and which forces the user to change his password after some
days (a simple example).

A password service provides two methods:

void changePasssword(String old, String new);
Session login(String user, String password);

The service has access to a database, which stores the user.
This simple example has a lot of possibilities to throw
exceptions.

First, you have a database access layer. It can throw
SQLException, which I would catch there and translate
into my own LowLevelSQLException. If I would use your
suggestion I would have a single exception for all
SQLExceptions.

How I would get programmatic access to the real reason
behind LowLevelSQLException? I can lose the connection,
which should be handled by cleanup of some resources but
I can also have a problem with the database structure,
which is a programmer error. So I have to divide it into
two exceptions. The first one I have to handle within the
service (but I have to notify the user), the second one
I should log and notify the user.

Another problem is a locked acount, the password has not
been changed for a long time. A login would generate an
exception, maybe AccountLockedException. If the account
isn't locked yet, the method can generate a
PasswordMustChangeException to notify the client. The
client application would display a dialog which lets the
user enter a new password. It wouldn't display a simple
output dialog which shows the error, the client must
react on the special exception.

The changePassword() method has also several possibilities
to throw an exception. There could be multiple password
policies which throw an exception: PasswordEmptyException,
PasswordTooShortException, PasswordMustContainLetterException.
There can also be an exception, if the user has given a wrong
old password (WrongPasswordException).

I wouldn't return such status values as return values,
I would use exceptions. But I have to react on the client
on the specific exception, every time the client must decide,
which dialog must be displayed.

Back to the exception framework. I can write this:

public void changePassword() throws PasswordEmptyException,
PasswordTooShortException, PasswordMustContainLetterException,
WrongPasswordException;

To prevent such a dependency (I can have more policies later),
I would use a superclass of the exceptions above, like
PasswordException.

public void changePassword() throws PasswordException;

Now I have the described problem: I know there were a
PasswordException,
But I don't know, what I have to display to the user within the
client.
I also could differ between PasswordPolicyException and
WrongPaswordException, but I cannot open a specific dialog for the
wrong policy.

So I have to use a long instanceof or getClause() construct to find
the right reason. Or I can use a unique error number within the
exception
and a switch-case to split the execution pathes.

A simple layer-X-throws-exception-X model will not work, I think.
The handler idea of markspace can be a solution, but I need the
handler
on the creation time of the exception. Or I have to use a factory
which provides a method for every service exception.

Too much possibilites...
Andre
 
A

Arved Sandstrom

Andre said:
Hi,

I think, this will not work in every case. If you have a user
management system, which allows the user to change his password
and which forces the user to change his password after some
days (a simple example).

A password service provides two methods:

void changePasssword(String old, String new);
Session login(String user, String password);
[ SNIP ]
Back to the exception framework. I can write this:

public void changePassword() throws PasswordEmptyException,
PasswordTooShortException, PasswordMustContainLetterException,
WrongPasswordException;

To prevent such a dependency (I can have more policies later),
I would use a superclass of the exceptions above, like
PasswordException.

public void changePassword() throws PasswordException;

Now I have the described problem: I know there were a
PasswordException,
But I don't know, what I have to display to the user within the
client.
[ SNIP ]

I don't see the specific problem here. You've got a number of exceptions
that you can throw, all of which are subclasses of a more general one.
When you throw the more general exception, PasswordException in this
case, you use the ctor that takes a Throwable as an argument. So no loss
of information.

On the other end, it's good practise to unwind an exception that you're
handling to determine the real root cause Throwable. Once you've got it,
the suggested handler idea could be used if that makes sense for the
specific client situation. In any case you will definitely know what
exact exception was originally generated.

AHS
 
M

markspace

I'm not sure, but it seems to me that you are mixing too much knowledge
of other layers here. You want to keep each layer self-contained.

For example, if you loose a connection, clean up and retry the
connection in the lower level database layer. Make a "best effort" to
delivery the query. If some number of retries fails (maybe just one
retry), then you have a real issue and should throw an exception, but
the higher level layer doesn't know or care why, it just shows "The
database is down, please try again later" to the user.

On the other hand, the problem with changing a stale password seems like
something the application itself should model, not the lower level
database. You could add a method "boolean isPasswordMustChange()"
method, or you could add "throws PasswordMustChangeException" to the
login() method. Both are equivalent. Both are part of the public API.
Not checking one is an application (and programmer) error.

It's OK to enforce the password policy with a low-level database trigger
or something similar, but the application should behave as if it's the
one that handles all of that logic.

The trick is to get the right information, return values or exceptions,
to the right layer, and then just handle them appropriately. You'd
never want to handle all errors in any one layer. That would be a
confusing job at best, unless they were handled completely generically
(i.e., the Java Logging API, which does use a factory pattern, btw).


More comments interspersed with yours below....


Andre said:
A password service provides two methods:

void changePasssword(String old, String new);
Session login(String user, String password);
How I would get programmatic access to the real reason
behind LowLevelSQLException? I can lose the connection,
which should be handled by cleanup of some resources but
I can also have a problem with the database structure,
which is a programmer error. So I have to divide it into
two exceptions. The first one I have to handle within the
service (but I have to notify the user), the second one
I should log and notify the user.


Don't. Log it. Programmers should test their code before release. If
they haven't, then they'll have to read the logs to determine why their
code failed in the field. A few trips to a frozen machine room far away
from civilization will be a good incentive for them to test better.

Another problem is a locked acount, the password has not
been changed for a long time. A login would generate an
exception, maybe AccountLockedException. If the account
isn't locked yet, the method can generate a
PasswordMustChangeException to notify the client. The
client application would display a dialog which lets the
user enter a new password. It wouldn't display a simple
output dialog which shows the error, the client must
react on the special exception.


I'd prefer that you add a method, or that the app just check if the
password is old and require the user to change it on its own. If the
programmer forgets to do this, just throw a low level database
exception, and log it. More trips to a cold machine room, and soon the
programmers will start to see the value of an adequate test harness.

The changePassword() method has also several possibilities
to throw an exception. There could be multiple password
policies which throw an exception: PasswordEmptyException,
PasswordTooShortException, PasswordMustContainLetterException.
There can also be an exception, if the user has given a wrong
old password (WrongPasswordException).


These should all be validated by the application first. If the app
forgets, then they can be logged as a low level db exception. Tell your
coders to learn to read the spec.

You appear to be trying to get the application to automagically adjust
to whatever the DB is enforcing at the moment. After a while, systems
become complex enough that you have to nail some behaviors down with a
written spec, and then don't change them until you've got at least one
version working and shipped. Decide on a password policy, and have both
the app and the DB enforce it independently.

You also mentioned something about having two separate systems. Note
that transmitting a password in clear text is almost always a serious
security concern. I hope your transmissions are encrypted.
 
A

Andre Rothe

I'm not sure, but it seems to me that you are mixing too much knowledge
of other layers here.  You want to keep each layer self-contained.

Maybe. I have tried it.
For example, if you loose a connection, clean up and retry the
connection in the lower level database layer.  Make a "best effort" to
delivery the query.  If some number of retries fails (maybe just one
retry), then you have a real issue and should throw an exception, but
the higher level layer doesn't know or care why, it just shows "The
database is down, please try again later" to the user.

Exactly what I have. The client must invalidate the current user
session and logs off the user.
On the other hand, the problem with changing a stale password seems like
something the application itself should model, not the lower level
database.  You could add a method "boolean isPasswordMustChange()"
method, or you could add "throws PasswordMustChangeException" to the
login() method.  Both are equivalent.  Both are part of the public API.
Not checking one is an application (and programmer) error.

I have decided to move it into the core system, because it is used by
several applications (clients), so I would have to program it several
times.
To prevent that, it is part of the core.
It's OK to enforce the password policy with a low-level database trigger
or something similar, but the application should behave as if it's the
one that handles all of that logic.

The application should get enough information to display the right
error
message and to show the change password dialog again.
The trick is to get the right information, return values or exceptions,
to the right layer, and then just handle them appropriately.  You'd

Right. Thats one of my problems, which I try to solve with a pattern
or
best-practice-approach.
never want to handle all errors in any one layer.  That would be a
confusing job at best, unless they were handled completely generically
(i.e., the Java Logging API, which does use a factory pattern, btw).

Thanks, I will check the source, to get more answers...
Don't.  Log it.  Programmers should test their code before release.  If
they haven't, then they'll have to read the logs to determine why their
code failed in the field.  A few trips to a frozen machine room far away
from civilization will be a good incentive for them to test better.

LOL, but I should notify the user, that something is wrong and the
current operation hasn't been finished. Ok, the message shouldn't
contain
the complete SQL statement...
I'd prefer that you add a method, or that the app just check if the
password is old and require the user to change it on its own.  If the
programmer forgets to do this, just throw a low level database
exception, and log it.  More trips to a cold machine room, and soon the
programmers will start to see the value of an adequate test harness.

I have decided to move this part in the Core too. It allows me to
throw
an exception in every case, the programmer of the client must catch
the exception only and shows a dialog. The application should be thin.
These should all be validated by the application first.  If the app
forgets, then they can be logged as a low level db exception.  Tell your
coders to learn to read the spec.

Same as above, I try to keep the application thin, because several
applications will use the core system. So I have to provide a lot
of detailled exception from the core to the clients and must react
on these within the client.
You appear to be trying to get the application to automagically adjust
to whatever the DB is enforcing at the moment.  After a while, systems

Right. That's the main focus. The core system can be widely
configured
and the application has to react on all those changes.

At the moment I have about 1000 positions where I have to create
exceptions
within the core.
I think, this is the right point to think about a generalized
exception
handling. The current method is very ugly and therefore I try to find
a method to make things better.
You also mentioned something about having two separate systems.  Note
that transmitting a password in clear text is almost always a serious
security concern.  I hope your transmissions are encrypted.

Yepp, the core and clients communicate per RMI, secured by SSL.

I have created a test system, which uses a factory now. At the moment
I create detailled exceptions within the core (i.e.
PasswordTooShortException),
but I bubble up these exceptions as more generalized exceptions
(i.e. PasswordException), which is an abstract class and superclass of
PasswordTooShortException. I use abstract classes to prevent
instantiation,
because they don't specify an error status, they group detailled
exceptions
only.

On the core interface I translate the PasswordException into a
CoreException
and re-throw it to the client. The core interface contains only
"throws CoreException". So I have to catch these exceptions within
the
clients:

try {
core.login();
} catch(CoreException e) {
// handle it
}

which simplifies the code a lot. With e.getCause() I can access the
reason of
the exception, but only as Throwable. The handler factory must use a
long
list of instanceof to find the correct handler implementation, which
is ugly.
Maybe the factory can act as a manager, I would have to register all
handlers.
The factory would ask every handler, whether or not it can handle the
given
exception:

public class WrongPasswordExceptionHandler implements ExceptionHandler
{

public static boolean accept(Throwable e) {
return (e instanceof WrongPasswordException);
}

}

This allows me to add more handlers dynamically, but it has a
disadvantage.

I have to prepare the factory for almost every class to access the
right
handlers within the right context (same exception can be processed by
different handlers for different parts of the application).

And I can run into problems, if I have to use different handlers for
a
single client class (two or more methods catch the same exception but
must handle it on different ways). There I must prepare such a
factory
just before the try-catch-statement which will pollute my client code
again.

Maybe I can extend the accept() method with class and method name,
which I could get from the call stack...

Andre
 
P

Pitch

This is pretty much the Right Way To Do It.

But note that in this case, you have to be careful about using
IllegalArgumentException, as it's a RuntimeException. If code in a deep
layer is doing input validation (say, taking a user-entered string and
looking something up in a database with it), then failure of validation
needs to be signalled with a checked layer-specific exception, otherwise
it will go through the upper layers and annoy the user.

On the other hand, if validation fails for a reason which could have been
caught by an upper layer (a parameter is null, an argument is too long or
the wrong colour, etc), then that's a programming error on the part of the
upper layer, and it's okay to throw an IllegalArgumentException. Although
it might still be wise to throw a checked exception.

all good points, thanks
 
P

Pitch

void changePasssword(String old, String new);
Session login(String user, String password);

The service has access to a database, which stores the user.
This simple example has a lot of possibilities to throw
exceptions.

First, you have a database access layer. It can throw
SQLException, which I would catch there and translate
into my own LowLevelSQLException. If I would use your
suggestion I would have a single exception for all
SQLExceptions.

If the database access is part of the password-service you can construct

new PasswordException(sqlException)

If you intend to clean-up afterwards, you do it in the db-layer, in a
try-finally, not in the password-service.
How I would get programmatic access to the real reason
behind LowLevelSQLException?

inheritance, see below

Another problem is a locked acount, the password has not
been changed for a long time. A login would generate an
exception, maybe AccountLockedException. If the account
isn't locked yet, the method can generate a
PasswordMustChangeException to notify the client. The
client application would display a dialog which lets the
user enter a new password. It wouldn't display a simple
output dialog which shows the error, the client must
react on the special exception.

If login() method is part of the password-service and it throws
AccountLockedException, this exception should also extended from
PasswordException, ok?


Now, what you need to do is to extend everything else also from
PasswordException, so don't use getCause() but use inheritance. Then if
you need to reopen a dialog when you get PasswordEmptyException or
PasswordMustContainLetterException you catch those exceptions and let
everything else go up (or show a different dialog)


Basically, you have one main service/layer exception
(PasswordExceptino). All exceptions produced by the internal logic of
that layer (invalid password/account) extend form that main eception. If
layer receives external exceptions (SQLException) it wraps them up in
the main exception as the cause. That external exception should be
handled in the external layer but information could be presented to the
user, perhaps in an abstract message "External exception occurred". Each
kind of internal exception provide tho GUI layer a way to change program
execution in the way as suitable (error-dialog, reopen login dialog,
etc..).


HTH
 
L

Lew

Andre Rothe said:
inheritance, see below

It could be said that chained exceptions are a better choice.

/** Throwable chainer.
* @param trow Throwable to chain.
* @param log Logger with which to log the chain.
*/
public static void chain( Throwable trow, Logger log )
{
for ( Throwable last = null, thr = trow;
thr != null && thr != last;
thr = (last = thr).getCause() )
{
log.debug( thr.getLocalizedMessage() );
}
}
 
P

Pitch

Andre Rothe said:


It could be said that chained exceptions are a better choice.

/** Throwable chainer.
* @param trow Throwable to chain.
* @param log Logger with which to log the chain.
*/
public static void chain( Throwable trow, Logger log )
{
for ( Throwable last = null, thr = trow;
thr != null && thr != last;
thr = (last = thr).getCause() )
{
log.debug( thr.getLocalizedMessage() );
}
}


I don't get this. If you are just trying to log all causes, why not use
logger?
 

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,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top