Unforeseen Exceptions in API
Suppose I'm writing an implementation to an interface:
publicinterface WeatherReader{
publicdouble readTemperature(int zipCode)throws ZipNotFoundException;
}
The client code passes in a zip code and expects to receive the temperature or a "zip code not found" exception as a response.
My question is, what if my implementation retrieves data from a data source that has checked exceptions (e.g. Flat File, Database, Sockets).
Using the Flat File data source as an example, file operations would throw an IOException. Would my implementation need to catch IOException and re-throw a RuntimeException (e.g. WeatherFileBadException)?
What is the correct way to handle this?
-Mike De Haan
# 1
> Suppose I'm writing an implementation to an
> interface:
>
> public interface WeatherReader {
> public double readTemperature(int zipCode) throws
> ZipNotFoundException;
>
>
> The client code passes in a zip code and expects to
> receive the temperature or a "zip code not found"
> exception as a response.
>
Then your design is wrong.
If the caller expects a non found return then it isn't an exception. You should provide a normal way to return something that indicates that.
> My question is, what if my implementation retrieves
> data from a data source that has checked exceptions
> (e.g. Flat File, Database, Sockets).
>
> Using the Flat File data source as an example, file
> operations would throw an IOException. Would my
> implementation need to catch IOException and re-throw
> a RuntimeException (e.g. WeatherFileBadException)?
>
> What is the correct way to handle this?
>
Depends on business needs and what the caller is actually doing. With your present design all you could return is a not-found error. But if you think that the above is reasonable then you need to return a system/internal error exception. So for example you shouldn't tell the user of a GUI that you couldn't find the zip code when the real problem is that the server isn't working correctly.
# 2
> > Suppose I'm writing an implementation to an
> > interface:
> >
> > public interface WeatherReader {
> > public double readTemperature(int zipCode) throws
> > ZipNotFoundException;
> >
> >
> > The client code passes in a zip code and expects
> to
> > receive the temperature or a "zip code not found"
> > exception as a response.
> >
>
> Then your design is wrong.
>
> If the caller expects a non found return then it
> isn't an exception. You should provide a normal way
> to return something that indicates that.
I disagree. "Exception" does not mean "unexpected." In particular, checked exceptions indicate something that *is* expected to go wrong occasionally, and is therefore expected to be dealt with by the caller.
One thing that *is* wrong is using an int for the zip code. Zip codes to not represent numerical quantities. They're just strings that happen to be composed only of digits. Except for zip+4 which has a dash, or Canadian postal codes which have a mixture of letters and numbers, etc.
jverda at 2007-7-12 17:16:30 >

# 3
> Using the Flat File data source as an example, file
> operations would throw an IOException. Would my
> implementation need to catch IOException and re-throw
> a RuntimeException (e.g. WeatherFileBadException)?
That's one option. As you know, you can't throw any checked exception except ZipNotFoundException from whatever implements that interface. There are two other options, neither of which I care for much:
1. Catch the IOException and ignore it. Return some predetermined value (for example Double.NaN) and document the fact that you might return that if you can't find the temperature for some reason. (Now that I thought of NaN I don't dislike this option as much. That is to say, I dislike it less... you know what I mean.)
2. Throw a ZipNotFoundException if you get the IOException. I think you'll find it obvious why this isn't a good design.
So given that interface I would choose option 0 or option 1 from the above list, depending on other factors of the design.
# 4
Hello,
You could think of throwing two exceptions, one for business failure and other for system failure.
Business failure exceptions (like ZIP code not found) could be propagated to the end-user, and the application should handle appropriately. That is, ask the user to re-enter.
System failure exceptions should be handled within the application (which tier, depends on your application design) and an useful message be displayed to the user (eg, An unexpected error, try again or so). You may also opt to wrap this system failure exception around the original exception object, so that you could provide a more meaningful log file with stacktrace.
-- Jithesh
# 5
>
> I disagree. "Exception" does not mean "unexpected."
> In particular, checked exceptions indicate something
> that *is* expected to go wrong occasionally, and is
> therefore expected to be dealt with by the caller.
>
I disagree with your disagreement.
If I am creating order entry system where the users search for a telephone number to find existing customers then it is completely inappropriate for exceptions to be used to indicate that the customer does not exist. That is something that happens often and so it is an expected message flow within the system.
On the other hand for if I have an automated posting system which posts shipped order and that is using the telephone number as a key then if the telephone number doesn't exist in the destination then it is an exception. In this case it is possible that it might occur, for example if a customer batch update did not work, but it isn't something that is normally expected during message flow.
For the OPs case it certainly seems possible that the users will enter zip codes that do not exist and those where it might not be possible that they exist. Those are normal data entry problems that should be dealt with. Now if someone enters a perfectly valid zip code which should exist but has not yet been updated (perhaps due to a batch failure) then maybe that should be an exception.
>
> One thing that *is* wrong is using an int for the zip
> code. Zip codes to not represent numerical
> quantities. They're just strings that happen to be
> composed only of digits. Except for zip+4 which has a
> dash, or Canadian postal codes which have a mixture
> of letters and numbers, etc.
Not to mention that Canada uses alphanumerics and it is rather easy to do business with Canada.
# 6
> I disagree with your disagreement.
>
> If I am creating order entry system where the users
> search for a telephone number to find existing
> customers then it is completely inappropriate for
> exceptions to be used to indicate that the customer
> does not exist. That is something that happens often
> and so it is an expected message flow within the
> system.
>
> On the other hand for if I have an automated posting
> system which posts shipped order and that is using
> the telephone number as a key then if the telephone
> number doesn't exist in the destination then it is an
> exception. In this case it is possible that it might
> occur, for example if a customer batch update did not
> work, but it isn't something that is normally
> expected during message flow.
>
> For the OPs case it certainly seems possible that the
> users will enter zip codes that do not exist and
> those where it might not be possible that they exist.
> Those are normal data entry problems that should be
> dealt with. Now if someone enters a perfectly valid
> zip code which should exist but has not yet been
> updated (perhaps due to a batch failure) then maybe
> that should be an exception.
I completely agree with your analysis in general but in this case I think an exception is proper. The method requires that the user enter a proper zip code. If the user enters an invalid zip code, it's an exception.
I would question using a checked exception here. I'd probably use a IllegalArgumentException for this in most cases.
I might create a checked exception for 'weather data unavailable for zipcode' which, depending on the implementation might included the case that the zip was not valid or any sort of IO error.
> One thing that *is* wrong is using an int for the
> zip
> code. Zip codes to not represent numerical
> quantities. They're just strings that happen to be
> composed only of digits. Except for zip+4 which has
> a
> dash, or Canadian postal codes which have a mixture
> of letters and numbers, etc.
>
> Not to mention that Canada uses alphanumerics and it
> is rather easy to do business with Canada.
Actually that was mentioned.
# 7
Exceptions should NOT be used to handle ordinary business process flow. And should not be used as a data input validation mechansim.
Exceptions are for dealing with application 'failures', e.g. cannot connect to relational database management system, messaging queue out of wack, etc. They are for dealing with out-of-the ordinary things that may come up at some time, but are not part of normal business processes.
A User entering an incorrect zip code because of a spelling/typing mistake should not be considered an application exception. The application should be designed to handle this naturally and indicate to the user that they had entered a zip code that is not found in the system. Again, this is not an exception, as JSchell points out above.
# 8
> Exceptions should NOT be used to handle ordinary
> business process flow. And should not be used as a
> data input validation mechansim.
>
> Exceptions are for dealing with application
> 'failures', e.g. cannot connect to relational
> database management system, messaging queue out of
> wack, etc. They are for dealing with out-of-the
> ordinary things that may come up at some time, but
> are not part of normal business processes.
I couldn't disagree more. Exceptions are a tool that should be used to handle responses for abnormal conditions. What is an abnormal condition is completely dependent on the design. There is no absolute rule you can apply here. How would you differentiate between finding the code but no weather data and not finding the code? It seems to me that you are advocating the 'error code as a return value' antipattern
If the system is designed to consider invalid or unknown postal codes as normal input then it shouldn't throw an exception for unknown postal codes. I would question that design in this case. There should be one method with the responisibility of finding data. Dealing with data entry errors should be handled elsewhere. Whether that happens before calling the lookup or upon failure is a another discussion entirely.
> A User entering an incorrect zip code because of a
> spelling/typing mistake should not be considered an
> application exception.
The assumption that this could only be caused by a user mistake is incorrect. It may very well have been caused by a system level problem.
> The application should be
> designed to handle this naturally and indicate to the
> user that they had entered a zip code that is not
> found in the system.
And how does throwing an exception from this method prevent that?
# 9
> I couldn't disagree more. Exceptions are a tool that
> should be used to handle responses for abnormal
> conditions. What is an abnormal condition is
> completely dependent on the design.
Yes, and as we know, there are many, many, many ways to design a working application. One could certainly design the application to use the Java Exception mechanisms to handle the "business" functions of the application. Designing in this fashion is questionable.
> There is no absolute rule you can apply here. How would you
> differentiate between finding the code but no weather
> data and not finding the code? It seems to me that
> you are advocating the 'error code as a return value'
> antipattern
There is no need to differentiate. Neither case should generate an exception. Whether you find a zip code or not, whether you find weather data or not, or any combination of the two. This is simply the case of data not in the system, please try again. This is a business use case, not the place for exceptions. You could certainly twist and abuse the exception mechanisms to suit the way you want to design the application, and the code will compile and work the way you want it too, but this is poor design...still.
> Dealing with data entry errors
> should be handled elsewhere. Whether that happens
> before calling the lookup or upon failure is a
> another discussion entirely.
How would you design the code to tell the difference between a spelling/typing error and someone intentionally entering a value that is not in the system? Is the user really supposed to know every single value in the system and make sure that he/she never enters an incorrect value? This is an unreasonable and unrealistic requirement.
Great for forum-speak and chatter, but still unrealistic.
Data values entered at the UI level should never generate application exceptions. This is a standard design principle and is understood.
> The assumption that this could only be caused by a
> user mistake is incorrect. It may very well have
> been caused by a system level problem.
I only stated one case, there may be many, many others. A system-level problem SHOULD THROW AN EXCEPTION. Whether the data value is
found in the database should not throw an exception.
System level problems can be designed to throw exceptions.
Data values entered by users that are not found in the database are not system level problems.
# 10
> > Exceptions should NOT be used to handle ordinary
> > business process flow. And should not be used as a
> > data input validation mechansim.
> >
> > Exceptions are for dealing with application
> > 'failures', e.g. cannot connect to relational
> > database management system, messaging queue out of
> > wack, etc. They are for dealing with out-of-the
> > ordinary things that may come up at some time, but
> > are not part of normal business processes.
>
> I couldn't disagree more. Exceptions are a tool that
> should be used to handle responses for abnormal
> conditions. What is an abnormal condition is
> completely dependent on the design. There is no
> absolute rule you can apply here. How would you
> differentiate between finding the code but no weather
> data and not finding the code?
Yes, but given that then why not use exceptions for every possible non-normal condition?
Note that the OP specifically defined that the interface does in fact expect that zip not found will occur.
The OP didn't define as an expected condition that the source (say a flat file) for zip codes do not exist. Nor that the file is ill-formed nor any other number of possible error conditions.
> It seems to me that
> you are advocating the 'error code as a return value'
> antipattern
Huh? Where is that documented?
# 11
>
> I completely agree with your analysis in general but
> in this case I think an exception is proper. The
> method requires that the user enter a proper zip
> code. If the user enters an invalid zip code, it's
> an exception.
>
Actually it doesn't say user, it says 'client'.
And the given requirements, in the OP, specifically expect that a the zip code might not exist. It is stated as invalid but rather non-existent. Non-existent might be because the input value is wrong or because the implementation does not have that implemented. One might further differentiate the possible cases but as expressed by the OP it is rather all encompassing and suggests that it is expected that data can not be returned.
> > Not to mention that Canada uses alphanumerics and it
> > is rather easy to do business with Canada.
>
> Actually that was mentioned.
So it was.
# 12
> My question is, what if my implementation retrieves
> data from a data source that has checked exceptions
> (e.g. Flat File, Database, Sockets).
Catch the underlying cause, log as necessary and wrap the exception in a ZipNotFoundException. e.g.
catch (SQLException sqlException)
{
sqlException.printStackTrace( System.err ) ;
throw new ZipNotFoundException( sqlException ) ;
}
Or with a different implementation.
catch (IOException ioException)
{
ioException.printStackTrace( System.err ) ;
throw new ZipNotFoundException( ioException ) ;
}
This way you preserve the interface, provide good exception handling and retain the exception information describing the cause.
> Would my
> implementation need to catch IOException and re-throw
> a RuntimeException (e.g. WeatherFileBadException)?
You should NEVER throw a RuntimeException in these circumstances.
# 13
Java Exceptions are for handling abnormal conditions, also referred to as exceptional conditions.
There is extra overhead inside the JVM when an exception occurs. When you are designing your classes, you need to make sure that you apply exception handling in the proper situations and avoid using exceptions for handling normal business processes.
A helpful hint is found inside the JVM behavior. Understanding the behavior of the JVM and what it does when it encounters exceptions should shed some light on how and when to code exceptions. Think method invocation stack and performance.
# 14
> >
> > I disagree. "Exception" does not mean "unexpected."
> > In particular, checked exceptions indicate something
> > that *is* expected to go wrong occasionally, and is
> > therefore expected to be dealt with by the caller.
> >
>
> I disagree with your disagreement.
jverd is correct. The normal path for this usecase is 'get temperature for postal code'. Anything that deviates from that normal flow is an Exception.
The temperature might be essential, or it could just as easily be optional, e.g part of a home page, containing chat info, news headlines, local weather etc.
# 15
Business logic must be used to handle the situation when a certain postal code is not found in the system, not involving instances of Exception.
This should be handled by code, not exceptions. A certain postal code not found in the system or a typing error should not be considered an abnormal condition. If you are thinking this way, you are not adequately addressing the business process and are absorbed with the coding aspect.
Typing errors, data that has not been loaded yet, are normal flows. They are variations of the use case and conditional processing should address this. The Java Exception mechanism does not apply here.
If you mix and mingled the Java Exceptions with normal business process, you add extra overhead and processing time that requires the JVM to work more.
If you are desiging the Hello World website, you are free to go crazy with exceptions. Let loose baby :o)
If you are designing an enterprise application and are concerned about performance you need to be careful how you design exceptions and need to ensure that they are handled at the right level. If they are too far down, there will be performance issues.
# 16
> I disagree with your disagreement.
>
> jverd is correct. The normal path for this usecase
> is 'get temperature for postal code'. Anything that
> deviates from that normal flow is an Exception.
>
The client expects that however. To me that doesn't seem like a deviation.
# 17
I apologize, as it seems I'm a little behind. For some reason I was not getting email notifications regarding the forum and I thought the topic had been ignored. It's seems I was quite mistake.
Thank you all for your posts. Your discussion is definitely bringing to light many areas of exception handling that can easily be over looked. I personally have learned a lot.
My original post was not intended to be an accurate depiction of a zip code weather service, but more or less to explore an idea. The weather "API" is completely fictitious for this discussion. I apologize for not doing my homework on Zip code formats.
I would like to add two things to the example that may or may not change your opinions.
1) The interface is not created by me and is therefore unalterable
2) We will assume that the API is not called directly by a user, a list of available zipcodes is displayed for the user to select one.
So far, I'm inclined to agree with MartinS and the idea of making the underlying exceptions the Cause of the ZipNotFoundException. The problem I see with this is it can sometimes be misleading to the client.
Given another method:
public void insert(ZipCode zip) throws AlreadyExistsException;
Do the same rules apply? I can't throw an AlreadyExistsException if the real problem was that my internet connection was down (jschell's point). Granted I would have logged the real exception and stacktrace, but the client code will try to pretty up the message and tell the user that his operation failed because the item already exists. In other words, what indication does the client code have to check the Cause, and where does it stop? I might have to display the Cause of the Cause of the Cause in order to get down to the truth of the matter.
A similar problem seems to occur frequently with implementing RMI in existing applications. Let's say I wrote a program to interfaces (a generally good rule to follow, right?). My entire application is ignorant of implementations. However, if I introduce an implementation that supports RMI, I now have to add the checked exception RemoteException to all of my interfaces. But the client doesn't need to know that the implementation has been remoted, right?
-Mike De Haan
# 18
> > I couldn't disagree more. Exceptions are a tool
> that
> > should be used to handle responses for abnormal
> > conditions. What is an abnormal condition is
> > completely dependent on the design.
>
> Yes, and as we know, there are many, many, many ways
> to design a working application. One could certainly
> design the application to use the Java Exception
> mechanisms to handle the "business" functions of the
> application. Designing in this fashion is
> questionable.
Why rejecting bad input a 'business function'?
> > There is no absolute rule you can apply here. How
> would you
> > differentiate between finding the code but no
> weather
> > data and not finding the code? It seems to me
> that
> > you are advocating the 'error code as a return
> value'
> > antipattern
>
> There is no need to differentiate. Neither case
> should generate an exception. Whether you find a zip
> code or not, whether you find weather data or not, or
> any combination of the two. This is simply the case
> of data not in the system, please try again.
Again, why does an exception prevent this?
> This is
> a business use case, not the place for exceptions.
> You could certainly twist and abuse the exception
> mechanisms to suit the way you want to design the
> application, and the code will compile and work the
> way you want it too, but this is poor design...still.
Blah blah blah. Your breath smells like cheese.
> > Dealing with data entry errors
> > should be handled elsewhere. Whether that happens
> > before calling the lookup or upon failure is a
> > another discussion entirely.
>
> How would you design the code to tell the difference
> between a spelling/typing error and someone
> intentionally entering a value that is not in the
> system?
Well, you could check a list of valid postal codes before attempting to retrieve weather data. The postal codes don't change often and could easily be cached.
> Is the user really supposed to know every
> single value in the system and make sure that he/she
> never enters an incorrect value? This is an
> unreasonable and unrealistic requirement.
And a stupid thing to point out.
> Great for forum-speak and chatter, but still
> unrealistic.
What a great point. You debate like a pro.
> Data values entered at the UI level should never
> generate application exceptions. This is a standard
> design principle and is understood.
Who said this is a UI level component. You would put a lookup to an external datasource in the UI? That's great design. Please tell us more of your wisdom.
> > The assumption that this could only be caused by a
> > user mistake is incorrect. It may very well have
> > been caused by a system level problem.
>
> I only stated one case, there may be many, many
> others. A system-level problem SHOULD THROW AN
> EXCEPTION. Whether the data value is
> found in the database should not throw an exception.
Ideally, the input should be checked for correctness up front but that may be costly or ungainly. If you do check the input, then not finding the data is a system level error. If not, just catch the exception and tell the user that the data wasn't found.
Are you not aware that you can catch exceptions?
> System level problems can be designed to throw
> exceptions.
>
> Data values entered by users that are not found in
> the database are not system level problems.
If they are supposed to be there they are.
# 19
> Yes, but given that then why not use exceptions for
> every possible non-normal condition?
Why not? Why return normally when an abnormal condition occurs?
> Note that the OP specifically defined that the
> interface does in fact expect that zip not found will
> occur.
How could he not? That's just good error handling.
> The OP didn't define as an expected condition that
> the source (say a flat file) for zip codes do not
> exist. Nor that the file is ill-formed nor any other
> number of possible error conditions.
>
> > It seems to me that
> > you are advocating the 'error code as a return
> value'
> > antipattern
>
> Huh? Where is that documented?
In my brain. It causes many bugs in many programs. Why do you think exceptions were created?
# 20
> Actually it doesn't say user, it says 'client'.
That make my point even more valid.
> And the given requirements, in the OP, specifically
> expect that a the zip code might not exist. It is
> stated as invalid but rather non-existent.
> Non-existent might be because the input value is
> wrong or because the implementation does not have
> that implemented. One might further differentiate
> the possible cases but as expressed by the OP it is
> rather all encompassing and suggests that it is
> expected that data can not be returned.
If I try to read from a file that does not exist, is that unexpected? Anytime I attempt to read from a file, I know that it could not be there, even if I check that it existed a moment earlier.
Do you think it's wrong for APIs to throw FileNotFoundExceptions?
# 21
> The problem I see with this
> is it can sometimes be misleading to the client.
>
> Given another method:
public void insert(ZipCode zip) throws AlreadyExistsException;
> Do the same rules apply?
There are always exceptions to rules :)
> I can't throw an
> AlreadyExistsException if the real problem was that
> my internet connection was down (jschell's point).
The exceptional flow for an 'insert zip code' usecase would be InsertionFailure. An exception should focus on why this usecase fails and less on the cause. If you need to convey the cause, then wrap it. Already exists, bad format, or connection lose would be causes. Therefore AlreadyExistsException seems to be a weak initial design for an interface to me.
Typically when I'm defining an interface I use a generic base exception for each package or module. I often derive an new base exception for each API call from that exception. I typically have a derived exceptions for each alternative flow.
If I introduced an AlreadyExistsException it would extend be from a base exception. The interface supports the base exception, the implementation throws exceptions which extend that base exception.
I say 'if' above because, an AlreadyExistsException potentially fails the concept of least intrusion. Unless an operation failure does harm, consider and then reconsider if it is even worth reporting to the user.
Getting an API right and flexible in the first place is critically important, because changing an existing API leaves you between a rock and hard place.
If your stuck with a poor API, refactoring it will take several release and lots of work to fix.
> I might have
> to display the Cause of the Cause of the Cause in
> order to get down to the truth of the matter.
Sometimes yes, as a general rule, you need to really consider if the end user is really interested in the cause. Perhaps the software program can do something to fix it ? e.g try to re-establish a timed out connection. Generally only report it, if THEY can do something to fix it and the software cannot.
> A similar problem seems to occur frequently with
> implementing RMI in existing applications. Let's say
> I wrote a program to interfaces (a generally good
> rule to follow, right?).
Yes.
> My entire application is
> ignorant of implementations.
Good, also remember that well chosen Exceptions make this easier/ more likely.
> However, if I introduce
> an implementation that supports RMI, I now have to
> add the checked exception RemoteException to all of
> my interfaces. But the client doesn't need to know
> that the implementation has been remoted, right?
In a typical enterprise environment fixing the cause is the job of a SysOp team, not the end user. In this scenario I often log and rethrow something useful to the end user. So WeatherServerUnavailable would be enough for the end user. Though I well aware that some purists consider logging and re-throwing to be an anti-pattern.
# 22
> > > There is no absolute rule you can apply here.
> How
> would you
> > differentiate between finding the code but no
> weather
> > data and not finding the code? It seems to me
> that
> > you are advocating the 'error code as a return
> value'
> > antipattern
>
> There is no need to differentiate. Neither case
> should generate an exception. Whether you find a
> zip
> code or not, whether you find weather data or not,
> or
> any combination of the two. This is simply the case
> of data not in the system, please try again.
>
> Again, why does an exception prevent this?
Usage of a Java Exception does not prevent this. As I mentioned, an application can be designed in this fashion. It is not a good way to use the Java Exception mechanism. This is not what it was created for and to grasp this, you need to understand completely how to define the data flow of a business process and how to implement conditional processing. Once you understand this, you will be able to distinguish between "abnormal (exceptional) conditions" and normal data flow.
The second thing to understanding why Java Exceptions should not be used in this fashion is the additional overhead in the JVM that comes with processing Exceptions.
All you need to do here is to return a message to the user saying that the zip code is not in the system. You certainly don't need to throw an Exception for this. But as I said, you can go right ahead and go crazy with Exceptions. If you feel the need to throw an Exception , go right ahead.
# 23
> > Yes, but given that then why not use exceptions for
> > every possible non-normal condition?
>
> Why not? Why return normally when an abnormal
> condition occurs?
>
I suppose if that is your take then there is no point in discussing it further.
My take is that the exception mechanism is probably going to be less efficient for handling situations that are basically normal.
> > Note that the OP specifically defined that the
> > interface does in fact expect that zip not found will
> > occur.
>
> How could he not? That's just good error handling.
Yes but errors such as no file, file permissions, bad file, etc are all possible error conditions as well. There could be others.
Those would be abnormal conditions in my code.
Something that is called out in the requirements and which is expected to normally occur would not normally be considered an exception.
>
> > The OP didn't define as an expected condition that
> > the source (say a flat file) for zip codes do not
> > exist. Nor that the file is ill-formed nor any other
> > number of possible error conditions.
> >
> > > It seems to me that
> > > you are advocating the 'error code as a return value'
> > > antipattern
> >
> > Huh? Where is that documented?
>
> In my brain. It causes many bugs in many programs.
> Why do you think exceptions were created?
I haven't seen "many" bugs caused by that. I can't actually recall any in java.
Of course with C/C++ I remember cases where people ignored error conditions. But there is nothing that prevents one from ignoring exceptions as well. I have certainly seen java code where numerous defined exceptions existed and yet generic catches were used even in cases where discrimination between different exceptions should have been made.
# 24
> > Actually it doesn't say user, it says 'client'.
>
> That make my point even more valid.
>
> And the given requirements, in the OP, specifically
> expect that a the zip code might not exist. It is
> stated as invalid but rather non-existent.
> Non-existent might be because the input value is
> wrong or because the implementation does not have
> that implemented. One might further differentiate
> the possible cases but as expressed by the OP it is
> rather all encompassing and suggests that it is
>expected that data can not be returned.
> If I try to read from a file that does not exist, is
> that unexpected? Anytime I attempt to read from a
> file, I know that it could not be there, even if I
> check that it existed a moment earlier.
>
> Do you think it's wrong for APIs to throw
> FileNotFoundExceptions?
It depends on the application.
If you write an application that polls for the existence of a file and moves it when found are you going to throw exceptions when it isn't there?
# 25
> All you need to do here is to return a message to the
> user saying that the zip code is not in the system.
> You certainly don't need to throw an Exception for
> this. But as I said, you can go right ahead and go
> crazy with Exceptions. If you feel the need to throw
> an Exception , go right ahead.
Please don't lose track of the fact that this is just an example. This is not a real API in a sense that everything has been thought though and actually exists in the coding world. I simply meant this as an example..
I understand the overhead involved with Exceptions in the JVM. The idea I was trying to express was not "why is this design crappy", but when given an interface design that cannot be changed, how can you add an implementation unforeseen by the original design and still remain "Java compliant". The intent of the interface in the OP was not to be directly called by the end user.
After reading this article:
http://dev2dev.bea.com/lpt/a/541
I think it's more a matter of perspective that justifies how exceptions should be handled (pardon me if this is what you've been saying all along).
From my API's perspective, a zip code could very well be passed-in that doesn't exist, just as a file may not exist on the harddrive causing a FileNotFoundException for many Java API calls.
From my weather application's perspective, I stole that responsibility away from the end user and placed it in the hands of the application. In other words, even though the API does not expect an invalid zip code to be entered, it very well could. My application would try it's best to prevent the user from having that ability (no free form fields), making this occurrence unexpected from the application's perspective.
If the application developer thought of every way that a bad zip code could be sent to the API, then the ZipCodeNotFoundException (from the Application's perspective) becomes an unexpected "nasty surprise".
-Mike De Haan
# 26
In the Hibernate framework there is an Exception class called PropertyNotFoundException.
This instance of Exception is created when the system reads a field name from a Hibernate configuration file and does not find a corresponding field in the relational table in the database.
This instance is created while the system is preparing the application's Hibernate code for action.
This is a good example of the Java Exception mechanism. During applicaiton startup, this Exception can and should be designed to prevent the application from running.
The Hibernate PropertyNotFoundException is quite different from the theorectical zip code not found exception of this post.
The Hibernate PropertyNotFoundException is created by a system-level problem. It has nothing to do with human/user input at any point.
# 27
> I understand the overhead involved with Exceptions in
> the JVM.
Keep in mind that that one shouldn't consider that too excessively.
If you have a processing section that is throwing 10,000 exceptions a second then it might be a problem.
One a minute isn't going to matter.
> From my weather application's perspective, I stole
> that responsibility away from the end user and placed
> it in the hands of the application. In other words,
> even though the API does not expect an invalid zip
> code to be entered, it very well could. My
> application would try it's best to prevent the user
> from having that ability (no free form fields),
> making this occurrence unexpected from the
> application's perspective.
>
However that description suggests an exception for a zip code not found. You don't expect that the zip will not be found.
That could be different though from whether there is weather data for that zip code.
# 28
> In the Hibernate framework there is an Exception
> class called PropertyNotFoundException.
>
> This instance of Exception is created when the
> system reads a field name from a Hibernate
> configuration file and does not find a corresponding
> field in the relational table in the database.
>
> This instance is created while the system is
> preparing the application's Hibernate code for
> action.
>
> This is a good example of the Java Exception
> mechanism. During applicaiton startup, this Exception
> can and should be designed to prevent the application
> from running.
>
> The Hibernate PropertyNotFoundException is quite
> different from the theorectical zip code not found
> exception of this post.
>
> The Hibernate PropertyNotFoundException is created by
> a system-level problem. It has nothing to do with
> human/user input at any point.
The description of the OP suggests exactly that however (for the specific zip code not found condition.)
# 29
> The Hibernate PropertyNotFoundException is quite
> different from the theorectical zip code not found
> exception of this post.
>
> The Hibernate PropertyNotFoundException is created by
> a system-level problem. It has nothing to do with
> human/user input at any point.
I think this is where my accursed weather example has lost people. I apologize tremendously for not having a to the point example.
I'm my opinion, the zip code not found exception and the property not found exception are identical from the perspective of the application. There's not a **** thing the user can do about either of them.
From the perspective of the API, however, hibernate's exception and the zip code exception are two totally different things. The hibernate API says, "there's no way a running application can recover from this normally, it's best to kill the app". The weather API says, "this could happen under normal circumstances, and an app can recover".
In this sense, I hope you can see the similarities between the ZipCodeNotFoundException and FileNotFoundException. In some cases, the user can recover if the app was intended to allow it.
Let's take another example using a database where all of the connection setting for the application are written to a properties file on the hard drive and only read once by the application. If there's an exception regarding the username or password field, the application would have to abort because there's no facility available to change the username and password during runtime (ApplicationFault).
Conversely, if the application did have the facility to re-enter the username and password field, the application should catch the exception and display a box allowing a retry.
Hibernate chose to make the PropertyNotFoundException unchecked because there would be very few, if any, applications that would allow the runtime configuration of the hibernate properties file. So why would they force client code to deal with the minority of cases.
Am I on the right track?
-Mike De Haan
# 30
>
> I think this is where my accursed weather example has
> lost people. I apologize tremendously for not having
> a to the point example.
>
> I'm my opinion, the zip code not found exception and
> the property not found exception are identical from
> the perspective of the application. There's not a
> **** thing the user can do about either of them.
>
> From the perspective of the API, however,
> hibernate's exception and the zip code exception are
> two totally different things. The hibernate API
> says, "there's no way a running application can
> recover from this normally, it's best to kill the
> app". The weather API says, "this could happen under
> normal circumstances, and an app can recover".
>
That a matter of degree however.
And despite what the hibernate docs might say there can be cases where ending the app would be the wrong thing to do. For example in a plugin system where one of the plugins uses hibernate only the plugin should fail not the entire application.
> In this sense, I hope you can see the similarities
> between the ZipCodeNotFoundException and
> FileNotFoundException. In some cases, the user can
> recover if the app was intended to allow it.
>
Still depends on the app.
For example if the only thing the app does is tell the user the weather then the fact that the user can still get the weather for miami isn't going to matter to someone who is actually in New York.
> Let's take another example using a database where all
> of the connection setting for the application are
> written to a properties file on the hard drive and
> only read once by the application. If there's an
> exception regarding the username or password field,
> the application would have to abort because there's
> no facility available to change the username and
> password during runtime (ApplicationFault).
>
Not necessarily. For example what about the following.
- The application is a 24x7 server.
- Maintainance occurred which updated the database (and deleted the correct user.)
In the above case what should happen is that the server just continues to attempt connections. If it stops then the admins will have to not only dealing with a wrong database but also restarting servers.
>
> Hibernate chose to make the PropertyNotFoundException
> unchecked because there would be very few, if any,
> applications that would allow the runtime
> configuration of the hibernate properties file. So
> why would they force client code to deal with the
> minority of cases.
>
Your assumption is incorrect.
All exceptions in hibernate are unchecked. That is a philosophical issue that I believe is discussed somewhere in the documentation.
# 31
In the case I mention, the Hibernate Exception is thrown inside a business object. The Exception is propogated to the Presentation tier servlet instance. The Hibernate Exception causes the creation of another Exception instance, i.e. an instance of javax.servlet.UnavailableException.
The client object of the Hibernate Exception is the servlet instance. When the client object receives an Exception, it then in return creates its own Exception which prevents the init() method from completing.
The Presentation tier then is temporarily disabled and the web application does not function until the cause of the Hibernate Exception is resolved.
Users will never experience the application when this Hibernate Exception is created. The application cannot be started until it is resolved.
The data that causes the Hibernate Exception is from the configuration file which is created by the application developer.
The data that would cause the (theoretical) zip code not found exception would be something that is created by the human being that is using the application.
# 32
> > Do you think it's wrong for APIs to throw
> > FileNotFoundExceptions?
>
> It depends on the application.
>
> If you write an application that polls for the
> existence of a file and moves it when found are you
> going to throw exceptions when it isn't there?
In the code that moves it, yes. In the code that polls, no. In the former, this is not an expected condition and is basically invalid input. In the latter, the point of the code is to return whether the file exists.
# 33
> > > Yes, but given that then why not use exceptions
> for
> > > every possible non-normal condition?
> >
> > Why not? Why return normally when an abnormal
> > condition occurs?
> >
>
> I suppose if that is your take then there is no point
> in discussing it further.
>
> My take is that the exception mechanism is probably
> going to be less efficient for handling situations
> that are basically normal.
My take is that code that looks up data does not have the responsibility of determining whether the key is valid. If you need to verify that a key is valid, then you should have something else to manage that. The end result is the same with greater separation of responsibilities.
> > > Note that the OP specifically defined that the
> > > interface does in fact expect that zip not found
> will
> > > occur.
> >
> > How could he not? That's just good error
> handling.
>
> Yes but errors such as no file, file permissions, bad
> file, etc are all possible error conditions as well.
> There could be others.
>
> Those would be abnormal conditions in my code.
>
> Something that is called out in the requirements and
> which is expected to normally occur would not
> normally be considered an exception.
It almost sounds like you are suggesting that the requirements force a particular design. My requirements change on a weekly basis and this approach is problematic for me. I'm actually in that situation right now because the tool that we are using limits my ability to design the way I would normally approach things. It's caused major delays as each requirement change has caused a design change.
> > In my brain. It causes many bugs in many
> programs.
> > Why do you think exceptions were created?
>
> I haven't seen "many" bugs caused by that. I can't
> actually recall any in java.
>
> Of course with C/C++ I remember cases where people
> ignored error conditions. But there is nothing that
> prevents one from ignoring exceptions as well.
If someone intentionally ignores something, there is no recourse outside of team management. But a return code can easily be accidentally ignored. In the case of checked exceptions, the compiler prevents them being ignored. In the case of runtime exceptions, the runtime prevents them from being ignored. A developer has actively ignore exceptions. Return codes are ignored by default. I fixed such a bug in my first few months on my new job and the author was very experienced with the return code approach.
> I
> have certainly seen java code where numerous defined
> exceptions existed and yet generic catches were used
> even in cases where discrimination between different
> exceptions should have been made.
Of course this can happen. I can die in a car crash even if I'm wearing a seatbelt.
http://en.wikipedia.org/wiki/Perfect_solution_fallacy
# 34
> > I suppose if that is your take then there is no point
> > in discussing it further.
> >
> > My take is that the exception mechanism is probably
> > going to be less efficient for handling situations
> > that are basically normal.
>
> My take is that code that looks up data does not have
> the responsibility of determining whether the key is
> valid. If you need to verify that a key is valid,
> then you should have something else to manage that.
> The end result is the same with greater separation
> of responsibilities.
If I am doing a customer lookup in a database to determine whether a customer exists or not prior to order creation then that is normal behavior.
In point of fact in database layers I never throw exceptions for not found queries. It is the callers responsibility to determine if a not found condition is exceptional or not.
> > Something that is called out in the requirements and
> > which is expected to normally occur would not
> > normally be considered an exception.
>
> It almost sounds like you are suggesting that the
> requirements force a particular design.
Err...of course they do.
The requirements that specify the inventory system for a mom and pop shop are going to drive to a design that is far different from those requirements for a multi-billion dollar company.
> My requirements change on a weekly basis and this
> approach is problematic for me. I'm actually in that
> situation right now because the tool that we are
> using limits my ability to design the way I would
> normally approach things. It's caused major delays
> as each requirement change has caused a design
> change.
Huh?
Requirements, by definition, require design changes. Why would you have requirements if that wasn't the case?
And if you have a problem with churn then it suggests you need to look at your architectural requirements and design (rather than application) and get a handle on that.
Or even just control your process.
It certainly doesn't have anything to do with specifics about exception versus not exception usage.
> >
> > Of course with C/C++ I remember cases where people
> > ignored error conditions. But there is nothing that
> > prevents one from ignoring exceptions as well.
>
> If someone intentionally ignores something, there is
> no recourse outside of team management. But a return
> code can easily be accidentally ignored. In the case
> of checked exceptions, the compiler prevents them
> being ignored.
Nope - there are no magic bullets.
try
{
MyClass.doit();
}
catch(MyCheckException e)
{
// Now it is ignored.
}
> In the case of runtime exceptions,
> the runtime prevents them from being ignored. A
> developer has actively ignore exceptions. Return
> codes are ignored by default. I fixed such a bug in
> my first few months on my new job and the author was
> very experienced with the return code approach.
>
Then I suppose you refuse to use hibernate?
> > I
> > have certainly seen java code where numerous
> defined
> > exceptions existed and yet generic catches were
> used
> > even in cases where discrimination between
> different
> > exceptions should have been made.
>
> Of course this can happen. I can die in a car crash
> even if I'm wearing a seatbelt.
>
> http://en.wikipedia.org/wiki/Perfect_solution_fallacy
Your supposition is that the alternative is more likely to lead to a correct solution in a measurable way.
I dispute that.
Code reviews lead to demonstrateably better code. Everything else is likely nothing more than subjective opinion.
# 35
> > > Do you think it's wrong for APIs to throw
> > > FileNotFoundExceptions?
> >
> > It depends on the application.
> >
> > If you write an application that polls for the
> > existence of a file and moves it when found are you
> > going to throw exceptions when it isn't there?
>
> In the code that moves it, yes. In the code that
> polls, no. In the former, this is not an expected
> condition and is basically invalid input. In the
> latter, the point of the code is to return whether
> the file exists.
So you are agreeing that specific requirements can lead to code that expects a not found condition as normal behavior and for that case no exception should be thrown?
That is all that I have been arguing.
# 36
> If I am doing a customer lookup in a database to
> determine whether a customer exists or not prior to
> order creation then that is normal behavior.
>
> In point of fact in database layers I never throw
> exceptions for not found queries. It is the callers
> responsibility to determine if a not found condition
> is exceptional or not.
And what happens if you go to update the record for a customer that was already found and it no longer exists? Do you throw an exception then?
> > > Something that is called out in the requirements
> and
> > > which is expected to normally occur would not
> > > normally be considered an exception.
> >
> > It almost sounds like you are suggesting that the
> > requirements force a particular design.
>
> Err...of course they do.
>
> The requirements that specify the inventory system
> for a mom and pop shop are going to drive to a design
> that is far different from those requirements for a
> multi-billion dollar company.
That's not what I am talking about.
> > My requirements change on a weekly basis and this
> > approach is problematic for me. I'm actually in
> that
> > situation right now because the tool that we are
> > using limits my ability to design the way I would
> > normally approach things. It's caused major
> delays
> > as each requirement change has caused a design
> > change.
>
> Huh?
>
> Requirements, by definition, require design changes.
> Why would you have requirements if that wasn't the
> case?
Many of the requirements would have been simple code changes. They would not have required high-level design changes as they did.
> And if you have a problem with churn then it suggests
> you need to look at your architectural requirements
> and design (rather than application) and get a handle
> on that.
We are trying. I haven't been around that long. But even if we do there are things that are out of our control. We are subject to a very large number of goverment regulations and those regulations change very often.
> Or even just control your process.
It's not my process, yet.
> It certainly doesn't have anything to do with
> specifics about exception versus not exception
> usage.
It has to do with technical design being drvien solely by requirements. We've had this discussion a lot and we are not going to agree. I think your approach means code will never be stable and you think mine is a waste of time. I don't think we need to get into it again. I shouldn't have brought it up.
> > If someone intentionally ignores something, there
> is
> > no recourse outside of team management. But a
> return
> > code can easily be accidentally ignored. In the
> case
> > of checked exceptions, the compiler prevents them
> > being ignored.
>
>
> Nope - there are no magic bullets.
Never said there was.
>try
>{
> MyClass.doit();
>}
>catch(MyCheckException e)
>{
>// Now it is ignored.
>}
That's explicitly ignoring the exception. You can't ignore an exception without doing something. Not ony are return codes ignored by default, they are also subject to the above mistake.
> > In the case of runtime exceptions,
> > the runtime prevents them from being ignored. A
> > developer has actively ignore exceptions. Return
> > codes are ignored by default. I fixed such a bug
> in
> > my first few months on my new job and the author
> was
> > very experienced with the return code approach.
> >
>
> Then I suppose you refuse to use hibernate?
Why do you suppose that? What I do and the code I make use of are different things. If hibernate uses return codes (I'm not exactly sure what you are referring to here) that doesn't mean I have to or that I can't handle that. But I think using return codes to hold errors is bad practice and even worse when the returned value is sometimes data and sometimes an error.
> Your supposition is that the alternative is more
> likely to lead to a correct solution in a measurable
> way.
I didn't say anything about measurable. I think that's a BS argument that seems to derive from a fundamental misunderstanding of science. Something can exist and/or be true and not be measurable. And that's not even the case here. It could be measurable, it's just not measured (that we know of.) There are other ways to evaluate reality. You can't reliably measure the effect that safetys have on preventing firearms accidents. But anyone who has had one prevent an accidental discharge knows that they do. Likewise, exceptions have, in my experience, forced me to pay attention to issues that I would have ignored. On the other hand, return codes do not force issues and in my experience are almost as often as they are not.
> I dispute that.
>
> Code reviews lead to demonstrateably better code.
Evidence?
> Everything else is likely nothing more than
> subjective opinion.
What's not a subjective opinion about "Code reviews lead to demonstrateably better code"?
# 37
> > > > Do you think it's wrong for APIs to throw
> > > > FileNotFoundExceptions?
> > >
> > > It depends on the application.
> > >
> > > If you write an application that polls for the
> > > existence of a file and moves it when found are
> you
> > > going to throw exceptions when it isn't there?
> >
> > In the code that moves it, yes. In the code that
> > polls, no. In the former, this is not an expected
> > condition and is basically invalid input. In the
> > latter, the point of the code is to return whether
> > the file exists.
>
> So you are agreeing that specific requirements can
> lead to code that expects a not found condition as
> normal behavior and for that case no exception should
> be thrown?
>
> That is all that I have been arguing.
The problem is that you have not understood what I was saying. Not the other way around.
The point I am making is that the end user requirements shouldn't define the internal structure of the design. I see too much code that assumes high-level requirements at each level of the design. This creates a brittle implementation. A change in the end product requirement requires modifying each successive piece. It also means that if another use of the same data is needed with different behaviors around exceptional cases, the reuse will be difficult if not impossible. To me, avoiding this is the essence of SRP.
In this case, the choice would likely be return null or throw and exception and won't make a huge difference either way. The return null method can be problematic if there's more than one reason that the data might not be found (something that could change over time.) Either way, the basic priniciple still holds. For low-level components, I find that it's usually better to assume that everything will work and throw otherwise and to handle high-level requirements in high-level components.
An example of this is parsing a string into an integer. My design might require that if the number is not parseable as an int, it should be interpreted in some other way, perhaps a large number of different successive parsing attempts. It doesn't make sense to embed this logic into the parsing method. The int parser should attempt to parse the int (whether it throws an exception is not important to me for this point). A different component should coordinate the high-level logic by calling each parser.
# 38
>
> And what happens if you go to update the record for a
> customer that was already found and it no longer
> exists? Do you throw an exception then?
>
So far as I know I always do.
The OP isn't updating a zip code though, they are querying for one.
> >
> > Err...of course they do.
> >
> > The requirements that specify the inventory system
> > for a mom and pop shop are going to drive to a design
> > that is far different from those requirements for a
> > multi-billion dollar company.
>
> That's not what I am talking about.
Whew. But then I obviously have no idea what you meant when you said "requirements force a particular design."
>
> We are trying. I haven't been around that long. But
> even if we do there are things that are out of our
> control. We are subject to a very large number of
> goverment regulations and those regulations change
> very often.
>
Ok.....but the point is that your particular situation does not relate to the industry in general (at least not in my experience per the discussion in this thread) nor to what I saw in the OPs initial post (noting that additional requirements from the OP clarified the position.)
>
> It has to do with technical design being drvien
> solely by requirements. We've had this discussion a
> lot and we are not going to agree. I think your
> approach means code will never be stable and you
> think mine is a waste of time. I don't think we need
> to get into it again. I shouldn't have brought it
> up.
>
You can note that I do not agree that it will make my code less stable.
>
> >try
> >{
> > MyClass.doit();
> >}
> >catch(MyCheckException e)
> >{
> >// Now it is ignored.
> >}
>
> That's explicitly ignoring the exception. You can't
> ignore an exception without doing something. Not ony
> are return codes ignored by default, they are also
> subject to the above mistake.
>
I agree.
But that is code that I have seen.
>
> Then I suppose you refuse to use hibernate?
>
> Why do you suppose that? What I do and the code I
> make use of are different things. If hibernate uses
> return codes (I'm not exactly sure what you are
> referring to here) that doesn't mean I have to or
> that I can't handle that. But I think using return
> codes to hold errors is bad practice and even worse
> when the returned value is sometimes data and
> sometimes an error.
Hibernate only uses unchecked exceptions.
Thus users are free to completely ignore them.
I suppose that leads to a discussion of what "stable" means.
So the fact that a server goes down in the middle of night because an exception occurred or because someone ignored a normal return value in either case suggests instability to me.
Please note of course that I am not suggesting that one shouldn't use exceptions. But rather that some interfaces specify that known functionality will exist. And thus by ignoring that I am not sure how a valid system could be created. It certainly wouldn't have been tested even to the requirements level. Because it can't function correctly if that is ignored.
>
> > Your supposition is that the alternative is more
> > likely to lead to a correct solution in a measurable
> > way.
>
> I didn't say anything about measurable. I think
> that's a BS argument that seems to derive from a
> fundamental misunderstanding of science. Something
> can exist and/or be true and not be measurable.
I believe love exists.
Someone can claim that physical beauty has nothing to do with how much one loves another.
That is an interesting subjective discussion. If a study existed that demonstrated that then I would probably find it highly suspect.
But when one claims that certain code idioms are more stable than others then I expect that in some way that opinion must be driven by something that is objective and can be measured.
Now if you want to state that using exceptions a lot is just the way you like to do it and you make it clear that you (subjectively) believe that it makes more code stable then ok.
That wasn't the way I read your postings however.
> And that's not even the case here. It could be
> measurable, it's just not measured (that we know of.)
> There are other ways to evaluate reality. You can't
> reliably measure the effect that safetys have on
> preventing firearms accidents. But anyone who has
> had one prevent an accidental discharge knows that
> they do. Likewise, exceptions have, in my
> experience, forced me to pay attention to issues
> that I would have ignored. On the other hand,
> return codes do not force issues and in my
> experience are almost as often as they are not.
Yes, I agree that you subjectively prefer that idiom.
I subjectively do not.
Those two subjective opinions carry the same weight.
It is rather easy to measure the performance impact that exceptions have.
Thus my idiom objectively beats yours.
Do you wish to argue that return values have more impact than exceptions?
>
> > I dispute that.
> >
> > Code reviews lead to demonstrateably better code.
>
> Evidence?
A number of studies published either in the IEEE journal or the ICM journal. I haven't read either in some time so perhaps something has refuted those since I last saw them.
>
> > Everything else is likely nothing more than
> > subjective opinion.
>
> What's not a subjective opinion about "Code reviews
> lead to demonstrateably better code"?
Sorry I thought you were aware of studies that demonstrate that.
# 39
> >
> > That is all that I have been arguing.
>
> The problem is that you have not understood what I
> was saying. Not the other way around.
>
Could be.
> The point I am making is that the end user
> requirements shouldn't define the internal structure
> of the design. I see too much code that assumes
> high-level requirements at each level of the design.
> This creates a brittle implementation. A change in
> the end product requirement requires modifying each
> successive piece. It also means that if another use
> of the same data is needed with different behaviors
> around exceptional cases, the reuse will be
> difficult if not impossible. To me, avoiding this
> is the essence of SRP.
>
That isn't the converse of this argument however.
The correct implementation of the use of exceptions versus return values should be a very minor topic in the ways to correctly implement a system based on the current requirements and known future requirements.
Ignoring that can certainly provide hundreds if not thousands of conceptual (not just individual code) problems.
> In this case, the choice would likely be return null
> or throw and exception and won't make a huge
> difference either way. The return null method can be
> problematic if there's more than one reason that the
> data might not be found (something that could change
> over time.) Either way, the basic priniciple still
> holds. For low-level components, I find that it's
> usually better to assume that everything will work
> and throw otherwise and to handle high-level
> requirements in high-level components.
Based on the additional requirements that the OP suggested, the correct solution is to throw an exception.
>
> An example of this is parsing a string into an
> integer. My design might require that if the number
> is not parseable as an int, it should be interpreted
> in some other way, perhaps a large number of
> different successive parsing attempts. It doesn't
> make sense to embed this logic into the parsing
> method. The int parser should attempt to parse the
> int (whether it throws an exception is not important
> to me for this point). A different component should
> coordinate the high-level logic by calling each
> parser.
Hopefully just a bad analogy....
Perhaps you are referring to the Integer methods? Those methods exist as they do because they are part of a library, not an application.
Or perhaps you are referring to a general parser? In that case if you are a "large number" then you should create an actual parser (tokenizer) rather than stringing together a bunch of exception driven parsing attempts.
# 40
> Or perhaps you are referring to a general parser? In
> that case if you are a "large number" then you should
> create an actual parser (tokenizer) rather than
> stringing together a bunch of exception driven
> parsing attempts.
Now, you are not advocating a premature optimization, are you?
# 41
> > Or perhaps you are referring to a general parser? In
> that case if you are a "large number" then you
> should
> create an actual parser (tokenizer) rather than
> stringing together a bunch of exception driven
> parsing attempts.
>
> Now, you are not advocating a premature optimization,
> are you?
Not, I am advocating that one should recognize when the design/requirments indicate that a parser/tokenizer exists and understanding how to create a parser versus creating code that simulates a parser by trying all different possibilities.
The two are significantly different.
# 42
> > > Or perhaps you are referring to a general parser?
> In
> that case if you are a "large number" then you
>should
> create an actual parser (tokenizer) rather than
>stringing together a bunch of exception driven
> parsing attempts.
>
> Now, you are not advocating a premature
> optimization,
> are you?
>
> Not, I am advocating that one should recognize when
> the design/requirments indicate that a
> parser/tokenizer exists and understanding how to
> create a parser versus creating code that simulates a
> parser by trying all different possibilities.
>
> The two are significantly different.
That's not what I meant. But a good attempt to change the subject.
# 43
> >
> > The two are significantly different.
>
> That's not what I meant. But a good attempt to
> change the subject.
Please do not assign motives to me.
I responded to what you posted.
Perhaps you did not see my initial comment in response to your analogy?
"Hopefully just a bad analogy...."
To expand on what I think you said....
"perhaps a large number of different successive parsing attempts"
I read "large number" and "successive" to mean a sequential attempt at parsing with failures leading to the next attempt.
And that is a poor way to implement a parser when there are large number of possibilities or even a medium number. So I pointed that the entire methodology is a poor design. And since that isn't what the OP was suggesting (that entire poor design methodolgy) I don't see what it has to do with this discussion.
Now if you didn't intend to mean a sequential progression of parsing elements attempts then rephrase so I can understand what you were intending with your analogy.
# 44
> Now if you didn't intend to mean a sequential
> progression of parsing elements attempts then
> rephrase so I can understand what you were intending
> with your analogy.
It wasn't an analogy. It was an example. I've had requirements in the past to attempt a number of conversions from string to date. In any event, I don't understand why it matters in the context of the discussion. Did you not understand what I was describing?
# 45
> >
> > Err...of course they do.
> >
> > The requirements that specify the inventory
> system
> > for a mom and pop shop are going to drive to a
> design
> > that is far different from those requirements for
> a
> > multi-billion dollar company.
>
> That's not what I am talking about.
>
> Whew. But then I obviously have no idea what you
> meant when you said "requirements force a particular
> design."
High-level requirements don't tell you how to design low-level technical components.
> Ok.....but the point is that your particular
> situation does not relate to the industry in general
> (at least not in my experience per the discussion in
> this thread) nor to what I saw in the OPs initial
> post (noting that additional requirements from the OP
> clarified the position.)
Really? You requirements never change? Even over the long term? You should consider having your code printed on to circuit boards.
> > It has to do with technical design being drvien
> > solely by requirements. We've had this discussion
> a
> > lot and we are not going to agree. I think your
> > approach means code will never be stable and you
> > think mine is a waste of time. I don't think we
> need
> > to get into it again. I shouldn't have brought it
> > up.
> >
>
> You can note that I do not agree that it will make my
> code less stable.
If the requirements never change it will be stable, I guess.
> > That's explicitly ignoring the exception. You
> can't
> > ignore an exception without doing something. Not
> ony
> > are return codes ignored by default, they are also
> > subject to the above mistake.
> >
>
> I agree.
>
> But that is code that I have seen.
I've seen it too. It's inexcusable. Not handling the return code is something that's easy to do without being incompetent.
I suppose you must understand that I don't believe that two solutions are equivalent if one is easier to screw up. If no one makes any mistakes they produce the same outcome but everyone does make mistakes.
> Hibernate only uses unchecked exceptions.
>
> Thus users are free to completely ignore them.
Not at runtime.
> I suppose that leads to a discussion of what "stable"
> means.
>
> So the fact that a server goes down in the middle of
> night because an exception occurred or because
> someone ignored a normal return value in either case
> suggests instability to me.
I'd much rather have a server go down than do something like corrupt the data in the database. I'd rather have to fix a system that goes down or throws back an error than explain why all the records that were entered during the day are no where to be found. When something bad happens, I like to know right away, preferably I'd like to be the first to know.
> Please note of course that I am not suggesting that
> one shouldn't use exceptions. But rather that some
> interfaces specify that known functionality will
> exist. And thus by ignoring that I am not sure how a
> valid system could be created. It certainly wouldn't
> have been tested even to the requirements level.
> Because it can't function correctly if that is
> ignored.
I don't follow this.
> But when one claims that certain code idioms are more
> stable than others then I expect that in some way
> that opinion must be driven by something that is
> objective and can be measured.
Do you believe that code written in Java is likely to be more reliable than something hand written in machine code? If not, do you think a programmer is more efficient in Java than with hand-written machine code?
> Now if you want to state that using exceptions a lot
> is just the way you like to do it and you make it
> clear that you (subjectively) believe that it makes
> more code stable then ok.
>
> That wasn't the way I read your postings however.
Suppose half of all cars had a button on the dash that had to be pressed in order to see the check-engine light. Assuming that engine problems are evenly distributed among cars, do you think drivers that have to press a button will be more likely to know when their car has a problem or those that do not will be more likely to know there is a problem?
> > And that's not even the case here. It could be
> > measurable, it's just not measured (that we know
> of.)
> > There are other ways to evaluate reality. You
> can't
> > reliably measure the effect that safetys have on
> > preventing firearms accidents. But anyone who has
> > had one prevent an accidental discharge knows that
> > they do. Likewise, exceptions have, in my
> > experience, forced me to pay attention to issues
> > that I would have ignored. On the other hand,
> > return codes do not force issues and in my
> > experience are almost as often as they are not.
>
> Yes, I agree that you subjectively prefer that
> idiom.
>
> I subjectively do not.
>
> Those two subjective opinions carry the same weight.
>
> It is rather easy to measure the performance impact
> that exceptions have.
Performance is not a concern unless it is shown to be a problem. You know that.
> Thus my idiom objectively beats yours.
The McNamara fallacy.
> Do you wish to argue that return values have more
> impact than exceptions?
Believing that only objective metrics are meaningful is the worst kind of foolishness because it sounds so convincing. It's really just blindness.
> > > I dispute that.
> > >
> > > Code reviews lead to demonstrateably better
> code.
> >
> > Evidence?
>
> A number of studies published either in the IEEE
> journal or the ICM journal. I haven't read either in
> some time so perhaps something has refuted those
> since I last saw them.
I would have to see how they measured code quality. I think it's impossible to measure it objectively in an accurate and meaningful way.
> >
> > > Everything else is likely nothing more than
> > > subjective opinion.
> >
> > What's not a subjective opinion about "Code
> reviews
> > lead to demonstrateably better code"?
>
> Sorry I thought you were aware of studies that
> demonstrate that.
I still don't believe there are.
# 46
> The point I am making is that the end user
> requirements shouldn't define the internal
> structure
> of the design. I see too much code that assumes
> high-level requirements at each level of the
> design.
> This creates a brittle implementation. A change in
> the end product requirement requires modifying each
> successive piece. It also means that if another
> use
> of the same data is needed with different behaviors
> around exceptional cases, the reuse will be
> difficult if not impossible. To me, avoiding this
>is the essence of SRP.
>
>
> That isn't the converse of this argument however.
>
> The correct implementation of the use of exceptions
> versus return values should be a very minor topic in
> the ways to correctly implement a system based on the
> current requirements and known future requirements.
The point above is not about the use of exceptions. It's about not building high-level requirements into base components.
> Ignoring that can certainly provide hundreds if not
> thousands of conceptual (not just individual code)
> problems.
Even if the above were about exceptions, it's a completely irrelevant point. Exceptions vs return codes is not a system design concern. It's a method/component level concern and at that level it's something that should not be ignored.
> In this case, the choice would likely be return
> null
> or throw and exception and won't make a huge
> difference either way. The return null method can
> be
> problematic if there's more than one reason that
> the
> data might not be found (something that could
> change
> over time.) Either way, the basic priniciple still
> holds. For low-level components, I find that it's
> usually better to assume that everything will work
> and throw otherwise and to handle high-level
> requirements in high-level components.
>
> Based on the additional requirements that the OP
> suggested, the correct solution is to throw an
> exception.
So if the requirements changed a year after the implementation in a way that would suggest using return codes to you, would you modify the design to no longer use exceptions?
# 47
> > Now if you didn't intend to mean a sequential
> > progression of parsing elements attempts then
> > rephrase so I can understand what you were
> intending
> > with your analogy.
>
> It wasn't an analogy. It was an example. I've had
> requirements in the past to attempt a number of
> conversions from string to date. In any event, I
> don't understand why it matters in the context of the
> discussion. Did you not understand what I was
> describing?
I did not understand how your example related to this discussion.
As I already pointed out the problem with that example was that the entire example was designed wrong, so it didn't matter whether exceptions were used in the implementation or not.
# 48
> >
> > That's not what I am talking about.
> >
> > Whew. But then I obviously have no idea what you
> > meant when you said "requirements force a particular
> > design."
>
> High-level requirements don't tell you how to design
> low-level technical components.
For the most part they do. A customer object might in general require a telephone number but the specific business requirements might lead to a design where there is no telephone number.
In the same way a order system for a mail order business with repeat business will lead to a design that supports that a customer either is likely to exist or must exist (maybe before one can order a sales person must set up the account.)
Conversely a book fair sales system will lead to customers that never exist until the order is taken (even repeat orders over several days might be handled as separate customers.)
>
> Ok.....but the point is that your particular
> situation does not relate to the industry in general
> (at least not in my experience per the discussion in
> this thread) nor to what I saw in the OPs initial
> post (noting that additional requirements from the OP
> clarified the position.)
>
> Really? You requirements never change? Even over
> the long term? You should consider having your code
> printed on to circuit boards.
I didn't say requirements don't change.
You described an environment that was seemingly forcing you into design decisions based on the way that process was handled in that environment.
Commonly even in chaotic process systems major problems with requirements and design often lead to complete re-factors, such as when the business model completely changes for example if a business starts out consumer focused and then changes to entirely vendor focused. In that case it isn't that exist software needs to change but rather that is no longer needed at all.
>
> > > I think your
> > > approach means code will never be stable and you
> > > think mine is a waste of time.
> >
> > You can note that I do not agree that it will make my
> > code less stable.
>
> If the requirements never change it will be stable, I
> guess.
That isn't what I said.
>
> But that is code that I have seen.
>
> I've seen it too. It's inexcusable. Not handling
> the return code is something that's easy to do
> without being incompetent.
>
> I suppose you must understand that I don't believe
> that two solutions are equivalent if one is easier to
> screw up. If no one makes any mistakes they produce
> the same outcome but everyone does make mistakes.
It isn't always a mistake.
Someone who doesn't realize that the database connection can fail is making a mistake. Someone who knows that it can, either via experience or perhaps even because it is called out in the requirements, but can still end up ignoring the exceptions. This, if one has a chance to ask, is usually explained by stating that they were going to fix it later but forgot. Or that they didn't have enough time to deal with it. I have certainly dealt with both of those in the past year alone.
>
> I suppose that leads to a discussion of what "stable"
> means.
>
> So the fact that a server goes down in the middle of
> night because an exception occurred or because
> someone ignored a normal return value in either case
> suggests instability to me.
>
> I'd much rather have a server go down than do
> something like corrupt the data in the database. I'd
> rather have to fix a system that goes down or throws
> back an error than explain why all the records that
> were entered during the day are no where to be found.
> When something bad happens, I like to know right
> away, preferably I'd like to be the first to know.
Sorry but your point here in terms of what we are discussing escapes me.
>
> > Please note of course that I am not suggesting that
> > one shouldn't use exceptions. But rather that some
> > interfaces specify that known functionality will
> > exist. And thus by ignoring that I am not sure how a
> > valid system could be created. It certainly wouldn't
> > have been tested even to the requirements level.
> > Because it can't function correctly if that is
> > ignored.
>
> I don't follow this.
If the requirments state that a customer might not exist then test cases need to exist to test this, both at the unit test level and system level.
And requirements are what drive this functionality (note again that I am not claiming that exceptions should never be used, but rather that the domain model drives the best usage.)
Thus regardless of whether one implements the existence check via exception or return value testing should still validate the functionality.
>
> > But when one claims that certain code idioms are more
> > stable than others then I expect that in some way
> > that opinion must be driven by something that is
> > objective and can be measured.
>
> Do you believe that code written in Java is likely to
> be more reliable than something hand written in
> machine code? If not, do you think a programmer is
> more efficient in Java than with hand-written machine
> code?
Subjectively I suspect that to be the case.
But I am rather certain that the software running the hard drives that I have been using for the last 30 years is not written in java. Yet I have never seen any of that software fail. I have however seen many examples of java code causing crashes.
>
> > Now if you want to state that using exceptions a lot
> > is just the way you like to do it and you make it
> > clear that you (subjectively) believe that it makes
> > more code stable then ok.
> >
> > That wasn't the way I read your postings however.
>
> Suppose half of all cars had a button on the dash
> that had to be pressed in order to see the
> check-engine light. Assuming that engine problems
> are evenly distributed among cars, do you think
> drivers that have to press a button will be more
> likely to know when their car has a problem or those
> that do not will be more likely to know there is a
> problem?
>
Sorry but your analogy does not apply.
My subjective opinion is that the vast majority of problems in software have nothing to do with what we are discussing. Some of the ones that I am certain to have so high an impact as to reduce the issue under discussion to the level of noise are the following (each of them, not as a group)
- Business driven concerns (business model changes, communications problems, etc.)
- Requirements problems
- Architecture problems
- Platform/production/install problems
- Design problems
- Technological problems
- Logic probloms.
- Lack of knowledge transfer.
A significant amount of my time over the last 10 years has been devoted to all of those. The only exception driven concerns at all are because either exceptions were deliberatly ignored or because not enough information was provided in an known exception case.
Actually I feel confident in stating that that last point along (not enough info for exceptions) is much more significant than the issue under discussion as well. Stack traces alone in all situations are not enough to diagnose or even understand errors.
> >
> > Yes, I agree that you subjectively prefer that
> > idiom.
> >
> > I subjectively do not.
> >
> > Those two subjective opinions carry the same
> weight.
> >
> > It is rather easy to measure the performance impact
> > that exceptions have.
>
> Performance is not a concern unless it is shown to be
> a problem. You know that.
Not the point however.
Two subjective opinions carry the same exact weight thus they cancel each other out.
Exception handling does produce a performance penalty.
So objectively, if there is any decision to be made it can only be made to favor using return values.
>
> > Thus my idiom objectively beats yours.
>
> The McNamara fallacy.
Nope. I pointed out that both of our opinions are based on subjective knowledge. I didn't claim that they didn't exist nor that they weren't important.
Nor did I claim that they were less important than the objective data. But because they both exist they cancel each other.
Other than that, myself I tend to regard give more relevance to that which can be measured versus those that can not when balancing between the two.
As an example though I might allow myself to suggest that C# and Java are the most widely used languages I realize that that is a subjective view. Objective data can either validate or invalidate that view. And in point of fact objective data does invalidate it (to an extent.)
However even so that doesn't mean that I do not realize that objectivity is still tempered with assumptions.
>
> Do you wish to argue that return values have more
> impact than exceptions?
>
> Believing that only objective metrics are meaningful
> is the worst kind of foolishness because it sounds so
> convincing. It's really just blindness.
>
And that is an opinion which we differ on.
Every one thinks that their opinions are the "best". That doesn't make it so.
I doubt that you claim that everyone's opinion is in fact the "best"?
Presuming that you answered no then exactly how do you wish to decide which opinions are better than others?
> >
> > A number of studies published either in the IEEE
> > journal or the ICM journal. I haven't read either in
> > some time so perhaps something has refuted those
> > since I last saw them.
>
> I would have to see how they measured code quality.
> I think it's impossible to measure it objectively in
> an accurate and meaningful way.
Of course there are any number of ways that one can critique such studies. I believe at least several of the studies used reported bugs. If I recall there were short term and long term measurements. But I could be mistaken as to the criteria.
There were certainly more than a couple studies though. And I can't recall any that ever came to the conclusion that code review impact was neutral or negative.
> >
> > Sorry I thought you were aware of studies that
> > demonstrate that.
>
> I still don't believe there are.
Naturally, with nothing more than my word that skepticism is healthy. I certainly don't intend to do the research necessary to find any of them.
Although I might ask do you think that, subjectively, code reviews are more likely to have no impact, a beneficial one or a negative impact?
# 49
> > > Now if you didn't intend to mean a sequential
> > > progression of parsing elements attempts then
> > > rephrase so I can understand what you were
> > intending
> > > with your analogy.
> >
> > It wasn't an analogy. It was an example. I've
> had
> > requirements in the past to attempt a number of
> > conversions from string to date. In any event, I
> > don't understand why it matters in the context of
> the
> > discussion. Did you not understand what I was
> > describing?
>
> I did not understand how your example related to this
> discussion.
OK, sorry. What can I do to spell it out for you?
> As I already pointed out the problem with that
> example was that the entire example was designed
> wrong, so it didn't matter whether exceptions were
> used in the implementation or not.
Really? You'd write a parser for that? Seems pretty absurd to me.
# 50
Here is my personal "best". Do not let exceptions cross the border between the Presentation and Business tier. Send a return code indicating success or failure from the Business tier.
Example code from Controller:
...
int result = 0;
result = businessdelegate.saveNewAccountRecord(recordDTO);
if (result <> 0) {
return mapping.findForward("exception");
}
// continue processing, everything is cool down below
....
This way the Controller never has to deal with any Java Exceptions that might surface down below.
RETURN CODES RULE!!!
# 51
> RETURN CODES RULE!!! sigh... joel, what have you done...
# 52
Any Architect would say this.
The preferred way is to catch all the exceptions in your code and throw a customized exception that would throw the inner exception as cause.
Ex:
catch(IOException e) {
throw new ZipNotFoundException(e);
}
catch(FileNotFoundException e) {
throw new ZipNotFoundException(e);
}
catch(DataAccessException e) {
throw new ZipNotFoundException(e);
}
# 53
>
> > As I already pointed out the problem with that
> > example was that the entire example was designed
> > wrong, so it didn't matter whether exceptions were
> > used in the implementation or not.
>
> Really? You'd write a parser for that? Seems pretty
> absurd to me.
For a "large number" which all generate exceptions on failure?
Definitely.
# 54
In another forum thread, jvaudry writes an interesting post:
http://forum.java.sun.com/thread.jspa?forumID=425&threadID=5177787
The post references a section of the Java API Documentation that I curse myself for not checking earlier:
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Throwable.html
In particular, this snippet:
"The implementation can communicate the details of the IOException to its caller while conforming to the Collection interface by wrapping the IOException in an appropriate unchecked exception."
This answers my original question about how to handle unforeseen exceptions and still remain java "compliant".