Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #12859

Re: Exception Handling

From Lew <noone@lewscanon.com>
Newsgroups comp.lang.java.programmer
Subject Re: Exception Handling
Date 2012-03-10 18:39 -0800
Organization albasani.net
Message-ID <jjh39f$crc$1@news.albasani.net> (permalink)
References <XnsA012D42584994jpnasty@94.75.214.39>

Show all headers | View raw


Novice wrote:
snip
> I have a utility class called LocalizationUtils which basically houses
> convenience methods dealing with i18n/l10n. One of its methods is
> getResources(). It expects two parameters, a String representing the
> "base name" (the leading part of the resource file name) and a locale.
>
> Here's the code for getResources() with all comments and error handling
> (aside from the empty catch block) stripped out:
>
> ====================================================================
> static public ResourceBundle getResources(String baseName, Locale locale
> {
>    ResourceBundle locList = null;

Don't use throwaway initializations, usually.

>    try {
>      locList = ResourceBundle.getBundle(baseName, locale);
>        }
>    catch (MissingResourceException mrExcp) {

Log and return 'null' if that's the recovery strategy for this exception.

>      }
>
>    return (locList);
> }
> ====================================================================
>
> The program which is executing is Foo. It has a method called
> getLocalizedText() which is the one executing
> LocalizationUtils.getResources(). The value of the baseName is a constant
> coded in an interface of constants called FooConstants which is
> implemented by Foo. Here's the code for getLocalizedText() without any
> error handling and just one relevant comment:

Using an interface to define constants is the "Constant Interface 
Antipattern". (Google it.) Use a class to define constants, not an interface.

An interface is there to define a type. Using it merely to define constants 
violates the spirit of interfaces, which is to avoid implementation.

> ====================================================================
> private void getLocalizedText() {
> 		
>    Locale locale = Locale.getDefault();
> 	
>    this.myText = LocalizationUtils.getResources(TEXT_BASE, locale);
>    this.myMsg = LocalizationUtils.getResources(MSG_BASE, locale);
>
>    /* Work with the localized resources. */  	
> }  		
> ====================================================================
>
> In terms of trouble spots, I know from experience that getResources()
> will throw a MissingResourceException, which is an unchecked exception,
> if the base name is misspelled. A null value in either parameter is also
> going to make the getResources() method fail: ResourceBundle.getBundle()
> will throw a NullPointerException if either parameter is null.
>
> My objective is to code getResources() and getLocalizedText() as
> professionally as possible. If the methods fail, I want to write a clear
> message to my log and the log record needs to include a stacktrace. (I'm

example:

   logger.error(message, exception);

> assuming that a console is not necessarily available to the operators
> running this program and I need to know where the error took place. Based
> on an article Arved suggested in another thread,
> http://www.javacodegeeks.com/2011/01/10-tips-proper-application-
> logging.html, I'm inclined to minimize "position" information - class
> name, method name, line number - in the log and instead get all of that
> from the stacktrace.)

I disagree.

I'd keep that class/method info in the log message. Line information is less 
valuable unless your methods are far, far too long.

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

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

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

Somewhere up the stack you should catch the exception and convert it to valid 
program state"

  catch(RuntimeException except)
  {
    forwardProgramControlToErrorScreen();
  }

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

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

> getResources(); then getLocalizedText() can have a try/catch block. The
> try/catch can detect the NullPointerException and write both the message
> and the stacktrace to the log.

Write the log at the point where you detect the error, not only further up the 
stack.

> But I gather that you should handle the error as close to where it
> happened as possible when you can. I'd tend to prefer to handle the null
> parameter values in getResources() except that I'm not sure how to write
> the stack trace to the log before any exception has happened.

  IllegalArgumentException exception = new IllegalArgumentException(msg);
  logger.error("Unable to proceed", exception);

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

> without the resources it is trying to get in getResources() so if I
> simply throw exceptions and write to the log and then let the program
> keep going, I'm simply going to get another NullPointerException on the
> first statement that tries to use the resources. I'm thinking that I
> should do a System.exit(1) after I've logged a null parameter or in the
> event of a MissingResourceException in getResources(). But I have yet to
> see System.exit() used in ANY example of error handling in any resource
> I've looked at so far.

Hmm.

-- 
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg

Back to comp.lang.java.programmer | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

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