The Artima Developer Community
Sponsored Link

Weblogs Forum
What's Your ShouldNeverHappenException?

73 replies on 5 pages. Most recent reply: Jan 27, 2007 12:01 AM by Gregg Wonderly

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 73 replies on 5 pages [ « | 1 2 3 4 5 | » ]
Morgan Conrad

Posts: 307
Nickname: miata71
Registered: Mar, 2006

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 4:52 PM
Reply to this message Reply
Advertisement
> So you just crash the app? Wouldn't you want to log it

For this exception to occur, the JVM is totally screwed up. Get the stack trace and look at it.

Most logging code is convoluted, think of all those XML configuration files and hierarchical Handlers and Loggers. More than likely your call to log the real problem will cause yet another crash and stack dump somewhere else and will confuse the issue.


Another example is if I clone() something known to be Cloneable. If it throws CloneNotSupportedException, I just throw an Error.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 5:09 PM
Reply to this message Reply
> So we should turn assertions off because:
> a) Google says so
> b) There is an option to do so :)

That's not what I said. I asked you why there would be an option to turn off exceptions if they should not be turned off. But it's really not my opinion that assertions 'have' to be turned off. What I mean to get across is that assertions in Java were designed to be turned off in production. Whether that was the proper choice is a debate that I'm not terribly interested in. I made that point very badly in my first post of the subject. I really don't have much opinion on whether assertions should be turned on or off. Realize, however, that if you are writing code to run in environments that are not under your control, there's a very good chance assertions will be turned off.

> In my view, an assertion verifies a property so important
> that if violated the program can no longer carry on. For
> example, if I have an internal method in my software that
> should never ever (ever!) receive a null argument, I'd
> like to verify it with an assertion. This isn't a runtime
> exception, this is an error in the way I have designed my
> code.

My general approach is that I try to develop any public method to have meaningful result for any possible input. Frequently this is not feasible or just doesn't make sense. In those cases I generally throw an IllegalArgumentException.

> If I've turned assertions off, then the state of my
> program is effectively random, who knows what is going to > happen?

That's definitely not how I design my code. Are you suggesting that AssertionErrors are being thrown as a normal activity of your production code? When your code therows an AssertionError, it should crash.

> The car analogy definitely isn't perfect. The engine one
> you mention is better. Would you rather have an engine
> that shuts down quickly when something goes mechanically
> wrong, or would you rather cross your fingers and hope it
> doesn't explode? (I think I'll make that the last analogy
> I ever make here, I'm terrible at them!)

I never said 'mechanically'. There was actually a recall for the Toyota Prius recently where the engine was shutting off at high-speeds. It was extremely dangerous. The fact of the matter is that when something goes horribly wrong, it's often the case that no course of action can be shown to be the proper one.

I actually follow a fail-fast philosophy so I'm not even sure why I made that analogy.

The point again is not about DBC principles. It's about using things the way they were meant to be used. Usually (but clearly not always) it's best to use tools in the way they were designed to be used.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 5:21 PM
Reply to this message Reply
> > So you just crash the app? Wouldn't you want to log it
>
>
> For this exception to occur, the JVM is totally screwed
> up. Get the stack trace and look at it.
>
> Most logging code is convoluted, think of all those XML
> configuration files and hierarchical Handlers and Loggers.
> More than likely your call to log the real problem will
> l cause yet another crash and stack dump somewhere else
> and will confuse the issue.

I've been working with message queues a lot lately. If you just crash in the middle of processing a message, it can have dire consequences, such as the message being lost. The code I have developed will actually avoid this situation but it took a good bit of work to get there.

Also, when this code runs, it is running in a remote autonomous process. There is no user that will see the stack trace and often it's impossible to capture it if it's not logged explicitly

Loggers are you friend. You should use them. I'd rather get an immediate alert and have a log file with interesting details than find out a month later that my code caused a $100K loss of business (it's happened) and have no way to determine what went wrong (that's happened too.)

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 5:37 PM
Reply to this message Reply
> > So you just crash the app? Wouldn't you want to log it
>
>
> For this exception to occur, the JVM is totally screwed
> up. Get the stack trace and look at it.

Looking back at your examples, I don't see anything about them that would suggest to me that the JVM is screwed up. That's the problem I have with that approach, I guess. You are representing it as a JVM failure when it's probably just a bug in a class or a configuration error.

Bill Venners

Posts: 2250
Nickname: bv
Registered: Jan, 2002

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 6:12 PM
Reply to this message Reply
> > Well, since I never expect these exceptions, and
> therefore
> > never want to catch them explicitly (just with a
> > last-ditch catch clause), I don't think it is worth
> adding
> > to the surface area of the design to create an
> exception
> > class for them.
>
> I think the point was for documentation. I guess if you
> see a ShouldNotHappenException in the logs, you can look
> at your co-worker and say, "that shouldn't have
> happened."
>
Yeah, but I still don't think it is worth adding to the surface area of the design given that these are really not expected to ever happen. It would be like having a HellFrozeOverException. Maybe it will happen someday, and if so you want the stack trace and debug info in the log file, but it is so unlikely that I think it's not worth adding another class to your codebase.

Bill Venners

Posts: 2250
Nickname: bv
Registered: Jan, 2002

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 6:20 PM
Reply to this message Reply
> > The feedback I got from the audience was that this is
> all
> > well and good, but some would have wrapped the
> exception
> > in an <code>AssertionError</code> instead of a plain
> old
> > <code>RuntimeException</code>, because that is
> > semantically more accurate.
>
> OK, it just dawned on my why this is very wrong.
> Assertions should not be turned on in production. That's
> s why it's fine that they extend Error: they will not be
> thrown.
>
Ah, that's a good insight into why AssertionError may be an Error not a RuntimeException. That may be enough ammo for me to justify my approach. I really consider the Error hierarchy as things I don't try to catch, because a thrown Error indicates things are so screwed up that by trying to log it myself I may bury the real cause because the logging attempt itself may fail with another Error. So I don't catch Throwable in my last-ditch catch clause (or fault-barrier as the article you pointed to calls it). I just catch Exception. I do want to catch these should-never-happen exceptions by that last-ditch catch clause so I can get the useful debug information in the log file, so in my case at least I think it makes sense to simply wrap them in a RuntimeException.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 6:24 PM
Reply to this message Reply
> Yeah, but I still don't think it is worth adding to the
> surface area of the design given that these are really not
> expected to ever happen. It would be like having a
> HellFrozeOverException. Maybe it will happen someday, and
> if so you want the stack trace and debug info in the log
> file, but it is so unlikely that I think it's not worth
> adding another class to your codebase.

I'm totally with you. Like I was saying, you can over think this. I just wrap it in a RuntimeException. If I see a RuntimeException, I know it was one of 'those' kinds of errors.

It would be nice to be able to have some sort of seamless wrapper though. Something that would allow you to do something like:
catch(RuntimeException[ThreadInterruptedException] e)


(the syntax is off the top of my head). In a functional style library, I have to deal with any kind of exception that the passed in handler class could throw but I don't want to declare throws Exception on the external API. The caller will usually know what kind of exceptions the handler it passed in can throw but I have to resort to instanceof checks on the wrapped exception if I want to handle them at the point of calling the execute(handler) method.

Bill Venners

Posts: 2250
Nickname: bv
Registered: Jan, 2002

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 6:26 PM
Reply to this message Reply
> In my view, an assertion verifies a property so important
> that if violated the program can no longer carry on. For
> example, if I have an internal method in my software that
> should never ever (ever!) receive a null argument, I'd
> like to verify it with an assertion. This isn't a runtime
> exception, this is an error in the way I have designed my
> code. If I've turned assertions off, then the state of my
> program is effectively random, who knows what is going to
> happen? I would rather exit quickly in a known way, than
> hope that my "should never happen" event isn't going to
> cause the world to end. From "The Pragmatic Programmer",
> "dead programs tell no lies". As an example, if I'm
> writing a tree algorithm, I might make the assertion that
> each node has one parent. If this is violated, none of my
> tree algorithms will make any sense.
>
Java has a different approach to checking pre-conditions than Eiffel. Eiffel uses assertions. What I do in Java, which is the accepted approach I think, is check with Java code and throw semantically meaningful runtime exceptions: NullPointerException, IllegalArgumentException, etc. This is a fail-fast strategy. It just doesn't use assertions or throw AssertionError.

Also, checking of preconditions won't generate what I call should-never-happen exceptions. Should-never-happen exceptions is the category of exceptions that I'm forced to catch in Java because they are checked, but I really don't think they will every be thrown. In any other language, I wouldn't catch them in the first place, because I wouldn't be forced to do so by the compiler.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 6:36 PM
Reply to this message Reply
> So I don't catch
> Throwable in my last-ditch catch clause (or
> fault-barrier as the article you pointed to calls it). I
> just catch Exception.

After one of my responses to Conrad, I decided to put in a last ditch effort to log Error at the last catch of the main method. As I was explaining to in that post, the environment is strange and it's not clear to me that there is anyway to recover unhandled throwables. So if I have a bad deployment and the code is throwing NoClassDefFoundErrors, it's guessing game to try to figure out what happened (even when run interactively) because this jvm doesn't seem to have a top level error handler.

I don't catch Throwable, though. I figure than any Throwable that comes out of the code will be an Exception or Error since the method being called doesn't throw Throwable (and Throwable is checked. I also figure that if the JVM is trashed, trying to log at the last point of the main method isn't going to make things any worse. It may not work but I can't see that there's any harm. I rethrow the Error just in case, though.

Frank Sommers

Posts: 2642
Nickname: fsommers
Registered: Jan, 2002

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 6:44 PM
Reply to this message Reply
> >
> Java has a different approach to checking pre-conditions
> than Eiffel. Eiffel uses assertions. What I do in Java,
> which is the accepted approach I think, is check with Java
> code and throw semantically meaningful runtime exceptions:
> NullPointerException,
> IllegalArgumentException, etc. This is a
> fail-fast strategy. It just doesn't use assertions or
> throw AssertionError.

Actually, I'd like to understand from this discussion when and how people use asserts in Java. I share Bill's view that things specified by an object's contract, such as not accepting null values, or not accepting arguments outside a certain range of values, etc, should be checked via exceptions, such as NullPointerException, etc.

But the other day I was perusing code from an open-source Java project, and this project followed a style where they check for those kinds of things via assert. I think that's wrong, and now that I understand that asserts can be turned off during runtime, that may not even work.

So I'm curious: What are the use-cases for which one should use assert? I personally admit, however shameful that may be, that I never found a need for assert in Java. Any enlightenment about what I'm missing would be most appreciated.

Morgan Conrad

Posts: 307
Nickname: miata71
Registered: Mar, 2006

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 7:07 PM
Reply to this message Reply
> Also, when this code runs, it is running in a remote
> autonomous process. There is no user that will see the
> stack trace and often it's impossible to capture it if
> it's not logged explicitly

I agree with you that capturing the stack trace is vital. Our apps run under DOS and you look at the black window. Where that isn't the case, for these "cannot possibly happen" errors, I'd prefer the simplest solution, avoiding any logging code

e.printStacktrace(System.err);


> Loggers are you friend.

Not sure I actually agree. In my experience, all to often some exception gets logged, the application continues anyway, and nothing is ever looked at. Cause the log is full of so much other crap. All to often logs become the anti-pattern.


I'll agree with you that my saying "the JVM is messed up" is simplistic. Maybe it's a bad class. But, in the examples I cited, if, in final prodution code, a class is Clonable and throws CloneNotSupportedException, what do you suggest? If a Document cannot give me it's contents between 0 and document.length(), what can I do?

Joel Neely

Posts: 10
Nickname: joelneely
Registered: Mar, 2003

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 7:21 PM
Reply to this message Reply
I recall hearing Tor Norbye (of Sun and the Java Posse) arguing that e.g. FileNotFoundException should never happen, I presume because the code could check before attempting to open a FileReader that the File existed and was readable. However, that still left me wondering:

1. Would one handle a failure of the pre-checks in the same way as FileNotFoundException?

2. Doesn't this allow a loophole for race conditions to create a hard-to-track-down bug (e.g. the file is removed after its existence is checked but before it is opened)?

Is there any best-practice wisdom on this point?

Bill Venners

Posts: 2250
Nickname: bv
Registered: Jan, 2002

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 9:17 PM
Reply to this message Reply
> So I'm curious: What are the use-cases for which one
> should use assert? I personally admit, however shameful
> that may be, that I never found a need for assert in Java.
> Any enlightenment about what I'm missing would be most
> appreciated.
>
You know, Frank, we actually do use assertions quite regularly, but just from within unit tests. That's the only place we use them conceptually, even though we don't use Java's assert mechanism itself, but rather methods like JUnit's assertThis and assertThat methods.

I had a few conversations about our non-use of Java's assert at JavaPolis, and we weren't the only ones who don't use them. I also asked Dave and Andy when to use assertions back when I interviewed them. This is their viewpoint:

http://www.artima.com/intv/defense3.html

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 9:24 PM
Reply to this message Reply
> > Also, when this code runs, it is running in a remote
> > autonomous process. There is no user that will see the
> > stack trace and often it's impossible to capture it if
> > it's not logged explicitly
>
> I agree with you that capturing the stack trace is vital.
> Our apps run under DOS and you look at the black window.
> . Where that isn't the case, for these "cannot possibly
> happen" errors, I'd prefer the simplest solution, avoiding
> any logging code
>
> e.printStacktrace(System.err);

I've worked with a lot of code that does this and it was terribly problematic from a maintenance and support perspective.

The advantage of logging is that you can put your logging in while you are coding and worry about where it will go later. For example, it's trivial to make all log statements that are error or above send an email or push a message to a queue or fill a special log file. If you just write to syserr and sysout you end up having to poll files for errors and that is messy and not terribly precise.

> > Loggers are you friend.
>
> Not sure I actually agree. In my experience, all to often
> some exception gets logged, the application continues
> anyway, and nothing is ever looked at. Cause the log is
> full of so much other crap. All to often logs become the
> anti-pattern.

But how does printing the stack trace solve that? Do you mean that the user will see it? It's very easy to configure a logger is to have it print to sysout. What do you lose? The situation you are describing is exactly what I saw when everything was printed to sysout and syserr. Using logging makes it much better because I can turn off all the super detailed garbage, or I can have multiple logs that have different levels of detail or split things along packages etc. There's really an infinity of possibilities with logging and very few possibilities with sysout and syserr. I actually push sysout and syserr to loggers because things being written there would otherwise be piped into the ether.

> I'll agree with you that my saying "the JVM is messed up"
> is simplistic. Maybe it's a bad class. But, in the
> examples I cited, if, in final prodution code, a class is
> Clonable and throws CloneNotSupportedException, what do
> you suggest? If a Document cannot give me it's contents
> between 0 and document.length(), what can I do?

I'm not saying ou can do something about it. What I (and Mr. Venners) are saying is that you should use a RuntimeException instead of an Error. This allows you to have a top-level (or bottom-level depending on how you look at it) sieve to catch all the problems that you can't really deal with. Errors are really for things like the JVM being out of memory or internal faults in the JVM. We are told not to catch them. If people start using Errors to capture things that are not related to the JVM bombing, we have to start catching Error and things get messy.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 9:32 PM
Reply to this message Reply
> 1. Would one handle a failure of the pre-checks in
> the same way as FileNotFoundException?

I can't see why not. Why do you ask?

> 2. Doesn't this allow a loophole for race
> conditions to create a hard-to-track-down bug (e.g. the
> file is removed after its existence is checked but before
> it is opened)?

Yes, exactly. This is one of the benefits of exceptions that is often overlooked. It's much easier to try something and handle the exception if it fails than try to make sure it will not fail before attempting it. Most of the time it's impossible unless you have transaction control and if you do, you are probably wasting time and creating more contention anyway.

It reminds me of the saying "it's easier to ask for forgiveness than to ask for permission." BTW, don't teach kids that saying.

Flat View: This topic has 73 replies on 5 pages [ « | 1  2  3  4  5 | » ]
Topic: What's Your ShouldNeverHappenException? Previous Topic   Next Topic Topic: C++ Delegation and Dynamic Inheritance


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us