The Artima Developer Community
Sponsored Link

Weblogs Forum
What's Your ShouldNeverHappenException?

73 replies on 5 pages. Most recent reply: Jan 26, 2007 9:01 PM 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 | » ]
James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 7:01 PM
Reply to this message Reply
Advertisement
> 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 think you are using them 'conceptually' whenever you throw a IllegalArgumentException or an IllegalStateException. I can see using assertions for private methods where I'm not inclined to verify that the othe method I wrote is passing in good arguments with an if and throw. But I would probably no keep these enabled for production. I probably should use them more for this kind of thing.

There was a blog here at some point (can't remember who) about not checking for nulls at every possible point in the code. Assertions are a good way to do that without being to loose-and-fast, I think.

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

The problem with the arguments they put forth here are that assertions are not required to achieve what they describe. That's how any application should behave. Assertions can be a tool but won't get you there alone. It sounds like this 'billion-dollar company' was catching AssertionError at least somewhere in their code.

If assertions threw RuntimeExceptions then I could see them as a more comprehensive solution. The way they are implemented in Java, however, limits their usefulness, IMO.

Brian Slesinsky

Posts: 43
Nickname: skybrian
Registered: Sep, 2003

Re: What's Your ShouldNeverHappenException? Posted: Jan 16, 2007 10:28 PM
Reply to this message Reply
I like to throw ImpossibleException. It gets a chuckle from other programmers when they first read it, which seems like sufficient justification. :-)

(Also, then you can easily find all usages of ImpossibleException when you're looking for similar cases, but that's not why I do it.)

When I'm working on someone else's project, I generally just throw a RuntimeException.

Brian Lloyd-Newberry

Posts: 2
Nickname: newbeb
Registered: May, 2006

Re: What's Your ShouldNeverHappenException? Posted: Jan 17, 2007 8:56 AM
Reply to this message Reply
It seems to me that IllegalStateException is a pretty good self documenting exception to throw. Two niggling things:

1. The javadoc says:
    Signals that a method has been invoked at an illegal or
inappropriate time. In other words, the Java environment or
Java application is not in an appropriate state for the
requested operation.


2. It doesn't have a cause constructor, so you would have to use initCause(Throwable cause) to set the cause (which can itself throw exceptions which you need to be aware of).

In internal APIs we create a NotGoingToHandleThisActOfGodException extending RuntimeException (it could extend IllegalStateException like a lot of the java.nio.channels Exceptions seem to do) and throw it because we get the causal constructors.

-Brian

http://newbebweb.blogspot.com/

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 17, 2007 9:04 AM
Reply to this message Reply
> It seems to me that IllegalStateException is a pretty good
> self documenting exception to throw. Two niggling things:
>
> 1. The javadoc says:
> Signals that a method has been invoked at an
> illegal or
> inappropriate time. In other words, the Java environment
> or
> Java application is not in an appropriate state for the
> requested operation.

Is there a problem here? That's how I use it. Generally it would be something like calling method B without first calling method A. This kind of requirement is something I avoid in designs as much as possible but I have had to do it.

> 2. It doesn't have a cause constructor, so you would have
> to use initCause(Throwable cause) to set the cause
> (which can itself throw exceptions which you need to be
> aware of).

I never noticed. I've never used it to wrap an exception. It use it for things like trying to execute SQL without a valid connection. I usually just wrap exceptions in a RuntimeException.

Morgan Conrad

Posts: 307
Nickname: miata71
Registered: Mar, 2006

Re: What's Your ShouldNeverHappenException? Posted: Jan 17, 2007 9:31 AM
Reply to this message Reply
> But how does printing the stack trace solve that? Do you
> mean that the user will see it?

Maybe I misinterpreted the topic. These are exceptions that SHOULD NEVER HAPPEN. So, in theory, they will never happen. And they were tested for. I throw an Error. Finally clauses do their thing and unless the Error gets caught the app crashes with a stack dump.

IllegalArgumentException and FileNotFoundException, which for some reason are dominating this thread, are certainly not in the "never" category. For those you should log, do all the standard error handling as you describe.

I'm only printing the CannotNeverHappen stack dump. If CanNeverHappen does happen, I don't trust logging to be properly configured or working. What if Logger.log throws an exception??? :-)




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

I throw subclasses of RuntimeException all the time. They are not, IMO, CanNeverHappens.

The top level sieve can catch Error too. Again quoting the javadocs for Error, they look right to me:

"serious problems that a reasonable application should not try to catch"

I guess "ImpossibleError" or "InconceivableError" (for fans of Princess Bride) is a little more clear, I may start using that...

Ricky Clarkson

Posts: 63
Nickname: rclarkson
Registered: Jul, 2006

Too lazy to read all the other comments Posted: Jan 17, 2007 9:58 AM
Reply to this message Reply
Hi Bill,

The API could help with this by providing a version that doesn't take a String, but members of an enum.

doStuff(thing,SupportedEncodings.UTF8); then there's no need to throw an UnsupportedEncodingException. Of course, there aren't that many permanently supported encodings, but you want to be able to treat the ones that are as if they are.

Plus, suppose you typed "UTF_8" instead of "UTF-8"; you want the compiler to tell you. It can with the enum solution, it can't with the String solution (well, it can, but not all the time, and with heuristics that really shouldn't be in a compiler).

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 17, 2007 11:17 AM
Reply to this message Reply
> > But how does printing the stack trace solve that? Do
> you
> > mean that the user will see it?
>
> Maybe I misinterpreted the topic. These are exceptions
> that SHOULD NEVER HAPPEN. So, in theory, they will
> never happen. And they were tested for. I throw an
> Error. Finally clauses do their thing and unless the
> Error gets caught the app crashes with a stack dump.

Yes, but 'should' is the key word. I'm sure you have enough experience to know that just because we believe something will never happen doesn't mean that we are right.

I guess the crux of the discussion is this, what advantage do you get from throwing Error as opposed to a RuntimeException? You are basically saying, 'this shouldn't happen but if it does I'm going to force a full meltdown of the system. Why do that? It's almost exactly the equivalent amount of code.

> I'm only printing the CannotNeverHappen stack dump. If
> CanNeverHappen does happen, I don't trust logging to be
> properly configured or working.

I don't think that your assumption that only a full VM failure will trigger these kinds of exceptions is correct. Take Bill Venners example of UnsupportedEncodingException. He's probably right that the format he mentions will always be supported. But if the exception were thrown, it's not likely to be caused by a foundering VM. It's more likely some sort of bug in some Java code. For example, someone comes along and changes it to another encoding that isn't universally supported and doesn't change the catch block. In any event, the exception isn't necessarily an indication that the VM is in question. You've forced an Error from an Exception. The VM didn't report an Error.

> What if Logger.log throws > an exception??? :-)

If you are paranoid about it, you can always print to syserr in a finally block associated with the call to the logger. That might be a good idea, actually. But realize that if the JVM is so f'ed up that it can't call the log method, it might also not be able to print the stack trace. I've seen this with bugs in native code. Basically the VM stopped cold with an error like 'an error occurred outside the VM'.

Morgan Conrad

Posts: 307
Nickname: miata71
Registered: Mar, 2006

Re: What's Your ShouldNeverHappenException? Posted: Jan 17, 2007 11:52 AM
Reply to this message Reply
> Yes, but 'should' is the key word.

IMO, the key word is never. I thought I have been making that clear, if not, my bad.

> I guess the crux of the discussion is this, what advantage
> do you get from throwing Error as opposed to a
> RuntimeException?

Why do we have any subclasses of Exception anywhere? So you can handle "this cant be happening" exceptions differetly than "the network is down" exceptions.

Code that catches "mere" RuntimeExceptions is all over.

You can catch the Error.

I'm not married to using Error, but, IMO, it's a bit better than RuntimeException.

> Take Bill Venners example of
> UnsupportedEncodingException. ...

> For example, someone comes along and
> changes it to another encoding that isn't universally
> supported and doesn't change the catch block.

If the encoding is configurable, then the exception isn't a never. But if your code catches the first exception, then tries to fallback to UTF-8, and I stare at the source code and see that, and it gets that exception, IMO that is the "never" case.


> If you are paranoid about it, you can always print to
> syserr in a finally block associated with the call to the
> logger. That might be a good idea, actually.

o.k., I can agree there.

re - a bit on loggers - at our company, there is a religious war between fans of Apache and Java loggers.

So when I write my code (mainly algorithms), I often have no idea what logger to call. That's another reason I tend to avoid loggers and throw exceptions. Let the guys writing the app can catch them and call their pet logger.

How do you guys handle this?

Mike Kaufman

Posts: 125
Nickname: mkaufman
Registered: Jan, 2007

Re: What's Your ShouldNeverHappenException? Posted: Jan 17, 2007 12:56 PM
Reply to this message Reply
I use my own unchecked exception for this and similar situations, which I've called InternalFailureRuntimeException.

This name is on the basis that if the exception does occur, the real cause is probably that I've misunderstood something or something in the code is incorrect, not as expected, not working properly etc (e.g. I passed the wrong argument, or sombody has commented something out, or a string literal is simply wrong, or we forgot about some particular possibility, or something elsewhere that affects it has changed, etc etc).

That's usually far more likely than the "obvious" reason given by the underlying exception (e.g the JVM doesn't support one of the mandatory charset names). For the same reason, I always put a message into the resulting unchecked exception that explains it in context (with the underlying exception as its cause), rather than just wrapping the impossible exception without explanation.

I kind of like the name "ShouldNeverHappenException" though!!!

A related issue is how to test such "should never happen" exceptions - given that they should never happen! Of course, in reality it's pretty much always possible for it to happen, for any or all of the reasons outlined above. It's just that there isn't a predictable way to make it happen under your own control... like if you want to test it.

And however unimportant you might consider the code (given that you think it can't happen), you might well want to have tests for it. For example, to check that the resulting exception has the correct message/cause/details/logging etc, or that other code handles the resulting exception correctly, or even just to avoid the "hole" in code-coverage reports.

In my own case, given that I think the exception can't happen, the last thing in the world I want is for the first ever execution of this code to happen at a customer site, after something has already gone "impossibly" wrong... and maybe have it produce the wrong message or something. From my point of view, if there's code there, I want to test it.

To let me test such code, I've standardized on inserting a call just before the "catch" to a method that uses generics to optionally throw any exception passed to it. In normal use this does nothing, but to test the handling of the impossible exception I can turn this "on" and have the relevant exception thrown. The use of generics keeps each individual call confined to the actual exception type involved, despite using a single such method for all exception types.

I've documented this approach at http://closingbraces.net/2006/12/19/exceptiontesting/ if it's of interest to anyone (and yes, my example of an impossible exception is also a charset name that all JVMs are guaranteed to support).

Max Lybbert

Posts: 314
Nickname: mlybbert
Registered: Apr, 2005

Error handling education Posted: Jan 17, 2007 2:32 PM
Reply to this message Reply
And here is exhibit A in why I always cry tears when a book says "error handling has been elided for brevity." Most of my error handling philosophy comes from the terse, but very content-rich, chapter on exceptions in The C++ Programming Language, because there simply aren't very many people willing to talk about it.

Please note, I am not saying any method suggested here is bad or unusable. I am saying that error handling is one of the black arts of programming because it's not adequately covered in education or computer books. And it's often only casually referred to anywhere else ("Oh, sure, I have much better strategies in my own code; and did I ever tell you about the half-orc, half-elf cleric/thief I played in our college D&D game?").

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 17, 2007 6:45 PM
Reply to this message Reply
> > Yes, but 'should' is the key word.
>
> IMO, the key word is never. I thought I have been making
> that clear, if not, my bad.

But if it's truly 'never' then why bother doing anything at all? The whole point of doing something is so that the app doesn't fold up like a cheap suit when CosmicRayFlippedABitException is thrown. Your approach kind of seems like: if this thing that you don't expect to happen happens, your app will crash very abruptly and inelegantly.

> > I guess the crux of the discussion is this, what
> advantage
> > do you get from throwing Error as opposed to a
> > RuntimeException?
>
> Why do we have any subclasses of Exception anywhere? So
> you can handle "this cant be happening" exceptions
> differetly than "the network is down" exceptions.
>
> Code that catches "mere" RuntimeExceptions is all over.

Code that catches all RuntimeExceptions or specific RuntimeExceptions? I only catch Exception in a few key places and when I do, that part of the app has gone down for the count.

> You can catch the Error.

You can but every authoritative document says you should not. For example, the first sentence of the documentation for the Error class is "An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch."

> I'm not married to using Error, but, IMO, it's a bit
> better than RuntimeException.

Why? Can you explain why your expectation that something shouldn't happen means it needs to be handled differently? It really has nothing to do with the severity of the error. If I can't connect to a database, my app is screwed. It's not going to do anything. If something weird happens that I didn't account for because I thought it would never happen, my app is screwed. Why do these need different types of handling?

> > Take Bill Venners example of
> > UnsupportedEncodingException. ...
>
> > For example, someone comes along and
> > changes it to another encoding that isn't universally
> > supported and doesn't change the catch block.
>
> If the encoding is configurable, then the exception isn't
> a never. But if your code catches the first exception,
> then tries to fallback to UTF-8, and I stare at the source
> code and see that, and it gets that exception, IMO that is
> the "never" case.

But developers are fallible. It may be a never case and a later change makes it possible. If we use an Error, it will crash like a meteorite, if we use a RuntimeException, the user will get a nice error window saying that something didn't quite go right and that they should contact support (if you use loggers effectively, support can already know, actually)

> > If you are paranoid about it, you can always print to
> > syserr in a finally block associated with the call to
> the
> > logger. That might be a good idea, actually.
>
> o.k., I can agree there.
>
> re - a bit on loggers - at our company, there is a
> religious war between fans of Apache and Java loggers.

That's a hard call. I think Sun blew it with that move. Log4J was already dominant. They should have incorporated it and worked with that team to add any improvements they desired. As far as I can tell, the JDKs logger still doesn't have a lot of the functionality that Log4j provides. The only advantage that I can see is that it comes with the JDK. I considered using it at my new job and after looking at it, I decided against it.

For my open-source project, I'll probably use the JDK version because I don't want to add a dependency to another jar.

> So when I write my code (mainly algorithms), I often have
> no idea what logger to call. That's another reason I tend
> to avoid loggers and throw exceptions. Let the guys
> writing the app can catch them and call their pet logger.

I may have given you the wrong impression here. I don't consider logging to be sufficient error handling at all. If you are writing components to be called from somewhere else, then you are absolutely correct to just throw the exception. All of the points I have been making are assuming a higher-level point in the code. I occasionally exceptions as they are being thrown but that's merely to help with debugging.

Do you use a debugger? I use loggers like dynamic comments. When I'm puzzling over some strange bug, I crank up logging to trace in a few key places and usually it's obvious what's wrong.

> How do you guys handle this?

I would say that you've got a team problem. I would say the best solution is to choose one or the other and make it a standard. It's really not that crucial which one it used and people should get over themselves. I hate drop bracket formatting and we use it at my new job. As much as it pains me to use it (with two-space indention!) I'm going along with it. Consistency is more important than my personal pain.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: Error handling education Posted: Jan 17, 2007 6:54 PM
Reply to this message Reply
> Please note, I am not saying any method suggested here is
> bad or unusable. I am saying that error handling is one
> of the black arts of programming because it's not
> adequately covered in education or computer books. And
> it's often only casually referred to anywhere else ("Oh,
> sure, I have much better strategies in my own code; and
> did I ever tell you about the half-orc, half-elf
> cleric/thief I played in our college D&D game?").

I truly is one of the more overlooked areas of programming. Does anyone come out of school knowing anything about it? It seems like the initiation for a new developer is for them to be beat-up in their first code project for not having any error handling.

I think it's just seen as a boring subject. It's not directly related to getting anything useful accomplished so I can see why. There's nothing sexy about writing fault-barriers.

Morgan Conrad

Posts: 307
Nickname: miata71
Registered: Mar, 2006

Re: What's Your ShouldNeverHappenException? Posted: Jan 17, 2007 7:08 PM
Reply to this message Reply
> But if it's truly 'never' then why bother doing anything
> at all?

Please reread the original post. A Checked Exception has been thrown. You can either delcare that you throw it, annoying an call stack, call System.exit(), log it and do nothing, which I feel is awful, or wrap it in some unchecked exception. As the original poster said, best practice is to wrap in some unchecked exception.


> If I can't connect to a database, my app is screwed.

Please, this example is beyond silly. Nobody would call failure to connect to a database a "never".

> If we use an Error, it will crash like a meteorite,

No, at minimum we print the stack trace and exit. If the main app wants, it can try / catch the main method, log it, even put up a nice "We Crashed Window". Just like Microsofts useless "we crashed" window.

As you quote, Error indicates that we don't want to recover. Not that we delete all logs, delete stderr, and call System.exit()

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 18, 2007 7:09 AM
Reply to this message Reply
> > But if it's truly 'never' then why bother doing
> anything
> > at all?
>
> Please reread the original post. A Checked Exception has
> been thrown. You can either delcare that you throw it,
> annoying an call stack, call System.exit(), log it and do
> nothing, which I feel is awful, or wrap it in some
> unchecked exception. As the original poster said, best
> practice is to wrap in some unchecked exception.

I don't need to reread it. What I am saying follows logically from our discussion. You are saying that you throw an Error because it will never happen. What that sounds like to me is that you think it doesn't really matter that the app will crash because "it won't happen". You don't need to worry about handling it. That's the same argument someone who is just squashing the exception would use. The whole point of wrapping the exception is in the case that it ever does happen, it will be handled. Wrapping in an Error is better than squashing it but it's still going to end up crashing the app unless you are catching Error, which is something you shouldn't be doing.

> > If I can't connect to a database, my app is screwed.
>
> Please, this example is beyond silly. Nobody would call
> failure to connect to a database a "never".

I think you misunderstand the point. I didn't say that. I said nothing close to that. You might want to look at it again. The point is that you are saying that you (or any other developers) incorrect assumption should be considered an extremely severe error. If this assumption proves wrong, it doesn't necessarily mean it's the end of the world. It just means the developer was wrong or something the assumption was based upon has changed. If I get an UnsupportedEncodingException for ebcdic, I don't throw an Error, I throw a RuntimeException. Why should I throw an Error if I get an UnsupportedEncodingException for UTF-8?

Again, I don't see how a developer making a assumption that turned out to be untrue translates into a more severe error than the db being unavailable. It kind of seems arrogant, actually.

> > If we use an Error, it will crash like a meteorite,
>

> No, at minimum we print the stack trace and exit.

That's what I mean.

> If the
> main app wants, it can try / catch the main method, log
> it, even put up a nice "We Crashed Window". Just like
> Microsofts useless "we crashed" window.

I do more than that in a non-Error failure. I don't mess with Errors because I have to trust the documentation.

> As you quote, Error indicates that we don't want to
> recover. Not that we delete all logs, delete
> stderr, and call System.exit()

But why limit yourself to the minimum error handling? What do you gain by doing this over throwing a RuntimeException?

Morgan Conrad

Posts: 307
Nickname: miata71
Registered: Mar, 2006

Re: What's Your ShouldNeverHappenException? Posted: Jan 18, 2007 9:20 AM
Reply to this message Reply
> I don't need to reread it.

Why am I talking to you then?

Oh, yeah, you can read my mind.

As usual James, (I've seen this happen in countless other Artima discussions) you refuse to read and listen to other people on this list and then claim to understand their thoughts.

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-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use