Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #12866
| From | Lew <noone@lewscanon.com> |
|---|---|
| Newsgroups | comp.lang.java.programmer |
| Subject | Re: Exception Handling |
| Date | 2012-03-11 11:07 -0700 |
| Organization | albasani.net |
| Message-ID | <jjipli$np7$1@news.albasani.net> (permalink) |
| References | <XnsA012D42584994jpnasty@94.75.214.39> <jjh39f$crc$1@news.albasani.net> <XnsA01385245AD09jpnasty@94.75.214.39> |
Novice wrote:
> Lew wrote:
>> Novice wrote:
>> snip
>>> try {
>>> locList = ResourceBundle.getBundle(baseName, locale);
>>> }
>>> catch (MissingResourceException mrExcp) {
>>
>> Log and return 'null' if that's the recovery strategy for this
>> exception.
>>
> Is that what I should do, return null if there is a problem getting the
> resource?
>
> I'm not sure if I should be returning anything at all. Maybe I should
> just log and stop the program?
I said *if* that's the strategy. What do you think? It may depend on the
specifics of the case.
> Fair enough. I've converted each constants interface to a class with a
> private constructor that throws an exception if someone tries to
> instantiate it.
How would that exception ever occur? How could "someone" ever try to call a
private constructor?
Don't throw code into a program that is provably never called.
> Tip 6 in the article makes the point that it is redundant and expensive
We've discussed this before, remember?
It's not expensive. When you're calling a logger statement for an error, the
cost of the error SWAMPS the time in the logger. Think about it.
> to get class, method and line information if it is already in the log
> message. A stacktrace will tell me all of that and more so shouldn't I be
> concentrating on getting a stacktrace, plus whatever I'll need that isn't
> in the stacktrace, like the date and time of the problem?
There are many who have answered this question, in response to your questions.
The answers covered a lot of approaches. Perhaps you recall them.
>>> Now, finally, here are some questions:
>>>
>>> Since the only exceptions I anticipate, MissingResourceException and
>>> NullPointerException, are unchecked exceptions, I gather than I
>>> shouldn't really do anything about them aside from logging when they
>>> happen. Okay,
>>
>> I disagree. You should end the program gracefully and get someone to
>> fix the programming error right away.
>>
> But what's the right way to end the program? System.exit()? That seems
Under operator control.
> the obvious way but as I've said further down, that doesn't seem to be
> the method used in the books and articles I've been reading. What's the
> better way?
Under operator control.
>>> fair enough; I certainly don't want to display the source code to my
>>> user, make them enter the correct value for the baseName, make them
>>> recompile the program and then run it again! But when/where should I
>>> log the error? For instance, if I mess up my coding somehow and
>>> inadvertently
>>
>> In the log file.
>>
> Yes, I realize that it goes in the log file. I mean when and where in my
> code do I do that? In getResource() or getLocalizedText()?
Wherever you detect the error.
>>> pass a null in the baseName, should getResources() be testing its
>>> input parameters individually to see if they are null and write a
>>> message to the log if they are null from within that method? I'm
>>> inclined to say yes
>>
>> Always check all parameters for validity, either by an explicit check
>> for a public or protected method, or by controlling what's passed to
>> package-private or private methods.
>>
>> A normal practice is to have an application-specific checked exception
>> to throw, or to throw the standard unchecked exception. For example:
>>
>> if (argument == null)
>> {
>> final String msg = "null argument";
>> IllegalArgumentException except = new
>> IllegalArgumentException(msg); logger.error(msg, except);
>> throw except;
>> }
>>
>> or similarly for application checked exception 'FooException'.
>>
>> throw new FooException(new IllegalArgumentException(msg));
>>
> At least one of the articles/books recommended against creating custom
> exceptions unless necessary, preferring to use existing exceptions where
> possible.
>
> The Java Tutorial puts it this way:
>
> "You should write your own exception classes if you answer yes to any of
> the following questions; otherwise, you can probably use someone else's.
>
> - Do you need an exception type that isn't represented by those in the
> Java platform?
> - Would it help users if they could differentiate your exceptions from
> those thrown by classes written by other vendors?
> - Does your code throw more than one related exception?
> - If you use someone else's exceptions, will users have access to those
> exceptions? A similar question is, should your package be independent and
> self-contained?"
>
> I don't _think_ I qualify to create my own exception under any of these
> conditions so I'm inclined to stay with the standard ones. Or am I
> missing something?
Yes.
It is common and frequently useful to create an application-specific checked
exception. Again, and I've said this many times, think about what will be
useful when troubleshooting a problem. Many times, a custom exception is
useful. It says that the underlying exception has been caught, logged and wrapped.
Runtime exceptions are dangerous because they slip past you. If you catch them
in a custom checked exception then code must handle it. All those runtime
exceptions are related, by dint of being exceptions within the same
application. BOOM! Qualified.
> Assuming I'm not, I'm inclined to use the first approach you suggested.
> Or perhaps use the technique but throw a NullPointerException. Bloch
> implied that IllegalArgumentException was fine for bad values but that
> NullPointerException was preferred where a parameter had a null value.
That's his opinion.
Many others think that 'IllegalArgumentException' makes more sense if it's an
argument that has an illegal value.
What do you think?
>> Somewhere up the stack you should catch the exception and convert it
>> to valid program state"
>>
>> catch(RuntimeException except)
>> {
>> forwardProgramControlToErrorScreen();
>> }
>>
> I went into Eclipse for a minute and amended getResources() to look like
> this:
>
> ========================================================================
> static public ResourceBundle getResources(String baseName, Locale locale)
> throws NullPointerException, IllegalArgumentException {
>
> if (baseName == null) {
> final String msg = "The base name cannot be null.";
> NullPointerException nullPointerException = new NullPointerException
> (msg);
> Logger logger = Logger.getLogger(CLASS_NAME);
> logger.log(Level.SEVERE, msg, nullPointerException);
> throw nullPointerException;
> }
>
> if (locale == null) {
> final String msg = "The locale cannot be null."; //$NON-NLS-1$
> NullPointerException nullPointerException = new NullPointerException
> (msg);
> Logger logger = Logger.getLogger(CLASS_NAME);
> logger.log(Level.SEVERE, msg, nullPointerException);
> throw nullPointerException;
Kind of a bad name for the variable, there.
What does your log look like with 'msg' printed twice?
> }
>
> //ResourceBundle resourceFile = null;
>
> try {
> ResourceBundle resourceFile = ResourceBundle.getBundle(baseName,
> locale);
> return(resourceFile);
> }
> catch (MissingResourceException mrExcp) {
> String msg = "Unable to find resources for base name, " + baseName + ",
> and locale, " + locale + ". Check the spelling of the base name.";
> throw new IllegalArgumentException(msg);
> }
> }
> ========================================================================
>
> That works just fine and my exception, with stacktrace, is logged before
> I've left getResources(). But why am I throwing the exception at the end
> of the if (baseName == null) block? Why not just exit the program
> gracefully instead of throwing the exception? If I pass it back up to the
Why, indeed?
> caller, what is is actually supposed to do, given that the message has
> been logged and recovery is not practical? Am I only passing it up so
> that getLocalizedText() can stop the program?
No, only the operator should stop the program.
The idea is to return to valid program state. RETURN TO VALID PROGRAM STATE.
*RETURN TO VALID PROGRAM STATE.*
>>> to that but I'm not sure what to do next. It seems pointless to carry
>>> on with getResources() since ResourceBundle.getBundle(baseName,
>>> locale) will fail on a NullPointerException with a null in either
>>> parameter. I could throw a NullPointerException so that
>>> getLocalizedText() can deal with it. But how do I get a stacktrace
>>> into the log if I follow that strategy? It's easy enough to get the
>>> stacktrace once I've caught an exception but I'm just talking about
>>> recognizing that an input parameter is null; there's no exception at
>>> that point to put in my log.
>>
>> There is if you create one. That's why Java has the 'new' operator.
>>
> Yes, I see that from your technique of creating one. I hadn't anticipated
> that approach.
That's why Java has the 'new' operator.
>>> If I let getResources() throw NullPointerException if either
>>> parameter is
>>
>> Better, use 'IllegalArgumentException'.
>>
>>> null, then I can let getLocalizedText() catch those
>>> NullPointerExceptions and get the stacktraces from the exception and
>>> write them to the log. In that case, I may as well just check the
>>> input parameters for nulls, and simply throw NullPointerException
>>> with a specific message within
>>
>> 'IllegalArgumentException'.
>>
> I have no strong feelings about this one way or the other but Bloch, on
> page 248 of Effective Java (2nd edition) says: "Arguably, all erroneous
> method invocations boil down to an illegal argument or an illegal state,
> but other exceptions are standardly used for certain kinds of illegal
> arguments and states. If a caller passes null in some parameter for which
> null values are prohibited, convention dictates that NullPointerException
> be thrown rather than IllegalArgumentException."
>
> Can we agree that whether I use IllegalArgumentException or
> NullPointerException in the situation I'm describing in my own code is
> simply a matter of personal style or preference? Or is there a reason to
> prefer IllegalArgumentException that Bloch failed to consider?
What do you think?
[snip]
>>> One other questions. When, if ever, should I execute System.exit()
>>> with a non-zero integer? In my example, I know that program Foo can't
>>> proceed
>>
>> Never. Program exit should be under user control.
>>
> So, given that my application has a GUI, leave the application suspended
> at the exception and make the user click the Close button? Why is that
> better than just exiting given that the program can't proceed without the
> missing resources in this case?
That depends. What constitutes valid program state? Should you just stop,
leaving the user wondering WTF happened? Should you perhaps come to a screen
that tells the user something went wrong, and give them some choices?
How do you feel when a program suddenly ends? What if you could've supplied
the missing "e" in the file name without having to start everything all over
again?
It all depends on the program, doesn't it?
Programs should really only end under operator control. But hey, do it your
way. What makes sense? What irritates the user? What's even possible?
> If this were a batch program rather than one with a GUI, would we close
> with System.exit()? Or wait for the operator to notice the program is
> suspended and make him kill it?
You tell me. The questions too vague. Describe the scenario precisely, with
the advantages and disadvantages of each approach. With more information about
your particular case, maybe I can advise.
--
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg
Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Next in thread | Find similar
Exception Handling Novice <novice@example..com> - 2012-03-11 01:51 +0000
Re: Exception Handling Lew <noone@lewscanon.com> - 2012-03-10 18:39 -0800
Re: Exception Handling Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2012-03-11 11:53 -0300
Re: Exception Handling Lew <noone@lewscanon.com> - 2012-03-11 10:51 -0700
Re: Exception Handling Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2012-03-11 16:35 -0300
Re: Exception Handling Novice <novice@example..com> - 2012-03-11 17:05 +0000
Re: Exception Handling Lew <noone@lewscanon.com> - 2012-03-11 10:53 -0700
Re: Exception Handling Novice <novice@example..com> - 2012-03-11 20:36 +0000
Re: Exception Handling Lew <noone@lewscanon.com> - 2012-03-11 11:07 -0700
Re: Exception Handling Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2012-03-11 17:00 -0300
Re: Exception Handling Novice <novice@example..com> - 2012-03-11 22:02 +0000
Re: Exception Handling Arivald <NOSPAMarivald@interia.pl> - 2012-03-11 21:03 +0100
Re: Exception Handling Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2012-03-11 18:31 -0300
Re: Exception Handling Novice <novice@example..com> - 2012-03-11 21:54 +0000
Re: Exception Handling Patricia Shanahan <pats@acm.org> - 2012-03-11 15:26 -0700
Re: Exception Handling Novice <novice@example..com> - 2012-03-11 23:23 +0000
Re: Exception Handling Lew <noone@lewscanon.com> - 2012-03-11 16:52 -0700
Re: Exception Handling Novice <novice@example..com> - 2012-03-12 17:16 +0000
Re: Exception Handling Lew <noone@lewscanon.com> - 2012-03-13 08:31 -0700
Re: Exception Handling Patricia Shanahan <pats@acm.org> - 2012-03-11 17:51 -0700
Re: Exception Handling Novice <novice@example..com> - 2012-03-12 17:26 +0000
Re: Exception Handling Arne Vajhøj <arne@vajhoej.dk> - 2012-03-12 14:49 -0400
Re: Exception Handling Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2012-03-11 20:46 -0300
Re: Exception Handling Novice <novice@example..com> - 2012-03-12 17:43 +0000
Re: Exception Handling Patricia Shanahan <pats@acm.org> - 2012-03-11 11:14 -0700
Re: Exception Handling Novice <novice@example..com> - 2012-03-11 22:35 +0000
Re: Exception Handling Lew <noone@lewscanon.com> - 2012-03-11 16:58 -0700
Re: Exception Handling Novice <novice@example..com> - 2012-03-12 15:44 +0000
Re: Exception Handling Gene Wirchenko <genew@ocis.net> - 2012-03-12 10:34 -0700
Re: Exception Handling Arivald <NOSPAMarivald@interia.pl> - 2012-03-11 20:34 +0100
Re: Exception Handling Novice <novice@example..com> - 2012-03-11 22:36 +0000
Re: Exception Handling Arne Vajhøj <arne@vajhoej.dk> - 2012-03-12 14:41 -0400
Re: Exception Handling Arne Vajhøj <arne@vajhoej.dk> - 2012-03-12 14:37 -0400
Re: Exception Handling Novice <novice@example..com> - 2012-03-12 22:43 +0000
Re: Exception Handling Lew <lewbloch@gmail.com> - 2012-03-12 16:11 -0700
Re: Exception Handling Arivald <NOSPAMarivald@interia.pl> - 2012-03-13 00:54 +0100
Re: Exception Handling Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2012-03-13 06:05 -0300
csiph-web