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
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