qpid-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Rupert Smith" <rupertlssm...@googlemail.com>
Subject Exceptions and error logging.
Date Mon, 09 Apr 2007 10:59:39 GMT
Exhibit A, Do not do this:

class MyException extends Exception
{
  MyException(Logger log, String message, Throwable t)
  {
    super(message, t);
    log.error(message, this);
  }
}

class MyLibrary
{
  ...

  public void myMethod()
  {
    ...

    if (wentWrong)
       throw new MyException(_logger, "It went wrong.", null);
  }
}

class MyCallingCode
{

  ...

  public void myOtherMethod()
  {
    try
    {
       ...
       myLib.myMethod();
    }
    catch (MyException e)
    {
       // Error already logged, do I log it again? Not sure so might as well
just to be certain...
       // But what if I am able to gracefully recover at this point? Logs
contain an error that wasn't really one, oh well...
       _logger.error("Got MyException: " + e.getMessage(), e);
    }
  }
}

Exhibit B, Do do this:

class MyException extends Exception
{
  MyException(String message, Throwable t)
  {
    super(message, t);
  }
}

class MyLibrary
{
  ...

  public void myMethod()
  {
    ...

    if (wentWrong)
       throw new MyException("It went wrong.", null);
  }
}

class MyCallingCode
{

  ...

  public void myOtherMethodGracefullHandling()
  {
    try
    {
       ...
       myLib.myMethod();
    }
    catch (MyException e)
    {
       // Retry the operation or perform some other compensating action that
sets things right again.
       ...

       // Might put in a log.debug or, at a push, info to explain what is
going on.
       _logger.info("Got MyException but managed to recover from it. No
worries.");
    }
  }

  public void myOtherMethodTopLevelHandler()
  {
    try
    {
       ...
       myLib.myMethod();
    }
    catch (MyException e)
    {
       // This is a top-level exception handler. Exceptions get here when
they have not been recovered from.
       _logger.error("Got MyException, oh dear its all gone wrong: " +
e.getMessage(), e);

       // Take some drastic action, e.g. clean up resources, abort the
transaction, call System.exit.
       ...
    }
  }
}

You could also use RuntimeExceptions in situations where you do not ever
expect to be able to recover from the error. This needs to be carefully
explained in the Javadoc for the throwing method, however, or you may take
the caller quite by surprise.

The problem with exhibit A, is that it logs the error too soon. An exception
becomes an error when it is caught and the catching code cannot recover from
it. Also when writing code that calls code that logs errors in exception
constructors (or maybe doesn't) can you be sure that the error is logged in
the constructor without tracing down to the throwing code and seeing how it
built the exception? In a situation of doubt, the natural thing is to log it
as an error again, creating two error log entries for the one exception.

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message