avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jeff Turner <j...@socialchange.net.au>
Subject [RT] IoC in exception handling?
Date Thu, 28 Jun 2001 14:10:30 GMT
Hi,

Java's exception handling is "active". It is driven by the callee, not
the caller. When an exception is thrown, the callee effectively calls
the catch {} block of the caller. So now if I'm using a passive API like
Avalon, and a Component throws an exception, doesn't that break IoC?
Since when does "a passive entity that performs a specific role"[1] get
to tell me, the caller, what to do?

To use the army "chain of command" analogy in the Avalon docs, a
Component throwing an exception is like a soldier forgetting their
orders, giving up and going home as soon as something goes wrong. If
that was the case, wars would not get fought and where would we all be
now, I should like to know? ;)
 
Wouldn't it be more appropriate to have a passive exception handling
system. We must acknowledge that, when a problem occurs, the callee
*must* contact the caller. The roles must temporarily be reversed.  So
how about using a passive SAX-like exception handling mechanism, where
the caller provides an ErrorHandler[2] implementation, which the callee
calls?

Here's an example. Let's say our Component wants to throw a fatal
exception. The regular Java exception handling, our caller would have:

class Caller {
  .. 
  try {
    callee.doSomething();
  } catch (SomeException e) {
    // handle error
	..
  }
  ..
}

and our callee would simply have:

class Callee {
  public void doSomething() throws SomeException {
    ..
    if (error) throw new SomeException("oops");
    ..
  }
  ..
}

Using a passive SAX-like ErrorHandler system, the caller could be
written:

class Caller implements ErrorHandler {

  ..
  callee.setErrorHandler(this);
  ..
  callee.doSomething();
  ..

  public void error(SomeException e) {
    // handle error
    ..
  }
}

And the callee:

class Callee {
  public void doSomething {
    ..
    if (error) {
	  errHandler.error(new SomeException("oops"));
	  return;
	}
	..
  }

  public void setErrorHandler(ErrorHandler e) {
    ..
  }
}

Now why is that better? Mostly because it allows for finer control.  The
callee can issue warnings on non-critical errors. It doesn't *have* to
exit on an error; it can "soldier on" if necessary, safe in the
knowledge that it's caller has been notified. This allows the callee to
throw multiple exceptions. Imagine the callee is managing threads, 3 of
which time out; how would you notify the caller of this with regular
Java exception handling?

Does the ErrorHandler system preserve IoC better than the first? Damn..
now I'm not so sure.. The choice is between the callee calling the
caller directly (throwing an Exception), or calling a well-defined
interface (ErrorHandler). However, in both cases, the callee **need know
nothing about the caller**. 

Um. So actually, exception handling doesn't break IoC. But then it's
demonstrably a lot less powerful than an ErrorHandler mechanism.

So how about providing, in org.apache.avalon.framework, an ErrorHandler
interface and DefaultErrorHandler implementation, just like SAX does?
That way, most people can continue to use Java's built-in exception
handling, and those who need the extra control can use ErrorHandlers,
all within the Avalon framework.


--Jeff

(who apologises for rambling, and changing his mind halfway..)


[1] http://jakarta.apache.org/avalon/framework/what-is-a-component.html
[2] http://www.megginson.com/SAX/Java/javadoc/org/xml/sax/ErrorHandler.html


---------------------------------------------------------------------
To unsubscribe, e-mail: avalon-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: avalon-dev-help@jakarta.apache.org


Mime
View raw message