Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Propagating exceptions in Java

2 views
Skip to first unread message

Daniel Wu

unread,
Sep 22, 1996, 3:00:00 AM9/22/96
to

I have a couple of questions about exception handling. In my code I
catch an exception and then rethrow it, using a different exception class:

------------------------------------------------------------
try {
...
}catch (IOException e) {
System.out.print (e.toString() + " -- Cannot read file");
e.printStackTrace ();
throw new MessageException (e.toString ());
}
------------------------------------------------------------

This produces the exception stack trace output:

java.io.IOException: read error -- Cannot read file
java.io.IOException: read error
at java.io.FileInputStream.read(FileInputStream.java)
at java.io.BufferedInputStream.fill(BufferedInputStream.java)
at java.io.BufferedInputStream.read(BufferedInputStream.java)
at java.io.BufferedInputStream.fill(BufferedInputStream.java)
at java.io.BufferedInputStream.read(BufferedInputStream.java)
at java.io.DataInputStream.readLine(DataInputStream.java)
at DataStore.CmdMessage.execute(CmdMessage.java:130)
at DataStore.DSServer.execute(DSServer.java:84)
at DataStore.DSServer_Skeleton.stub1001(DSServer_Skeleton.java:68)
at DataStore.DSServer_Skeleton.dispatch(DSServer_Skeleton.java:115)
at horb.orb.ThreadServer.MethodCallLoop(ThreadServer.java)
at horb.orb.ThreadServer.createInstance(ThreadServer.java)
at horb.orb.ThreadServer.run(ThreadServer.java)

Elsewhere in the code, I catch the MessageException that was re-thrown
earlier, and reprint the stack trace:

------------------------------------------------------------
try {
...
} catch (MessageException e) {
e.printStackTrace ();
throw new HORBException (e.toString ());
}

------------------------------------------------------------

Now the stack trace appears as:

DataStore.MessageException: java.io.IOException: read error
at DataStore.CmdMessage.execute(CmdMessage.java:138)
at DataStore.DSServer.execute(DSServer.java:84)
at DataStore.DSServer_Skeleton.stub1001(DSServer_Skeleton.java:68)
at DataStore.DSServer_Skeleton.dispatch(DSServer_Skeleton.java:115)
at horb.orb.ThreadServer.MethodCallLoop(ThreadServer.java)
at horb.orb.ThreadServer.createInstance(ThreadServer.java)
at horb.orb.ThreadServer.run(ThreadServer.java)


Here I have lost a bit of the stack trace information. In the earlier
print out, the stack trace zero'ed in on the precise line in the code
where the original exception was triggered (130):

at DataStore.CmdMessage.execute(CmdMessage.java:130)

but in the subsequent print-out, it provides the line where the
MessageException was thrown (138):

at DataStore.CmdMessage.execute(CmdMessage.java:138)


====================================================================
QUESTION 1: Is there any way to preserve the original line
number the exception was triggered when propagating
the exception?
====================================================================


I do the same thing again: catch the MessageException and rethrow it
using a new exception class called a HORBException:

throw new HORBException (e.toString ());

When I catch this latest exception and print the strack trace, I get:

horb.orb.HORBException: DataStore.MessageException: java.io.IOException: read error
at DataStore.DSServer.execute(DSServer.java:94)
at DataStore.DSServer_Skeleton.stub1001(DSServer_Skeleton.java:68)
at DataStore.DSServer_Skeleton.dispatch(DSServer_Skeleton.java:115)
at horb.orb.ThreadServer.MethodCallLoop(ThreadServer.java)
at horb.orb.ThreadServer.createInstance(ThreadServer.java)
at horb.orb.ThreadServer.run(ThreadServer.java)


Because I throw each exception by writing

throw new Exception (e.toString ());

the names of each exceptions I previously caught are now prepended to
each successive exception name. I would prefer to have the exception
output formatted as:

java.io.IOException: read error -- Cannot read file
at DataStore.CmdMessage.execute(CmdMessage.java:130)
DataStore.MessageException:
at DataStore.DSServer.execute(DSServer.java:84)
horb.orb.HORBException:
at DataStore.DSServer_Skeleton.stub1001(DSServer_Skeleton.java:68)
at DataStore.DSServer_Skeleton.dispatch(DSServer_Skeleton.java:115)
at horb.orb.ThreadServer.MethodCallLoop(ThreadServer.java)
at horb.orb.ThreadServer.createInstance(ThreadServer.java)
at horb.orb.ThreadServer.run(ThreadServer.java)

The line numbers under each exception would indicate where the exception
was caught (not thrown).

====================================================================
QUESTION 2: Is it possible to reformat the stack trace
in this manner?
====================================================================

In my code, I want to delay printing the exception and its stack trace
until it percolates up to an an appropriate point in the calling chain.
In order to do that I would like to preserve as much information as
possible about the exception context. Can this be done in Java?

Daniel

//----------------------------------------------------------------------
// Daniel Wu dan...@cs.ucsb.edu
// Dept of Computer Science, UCSB, 91306, USA
//----------------------------------------------------------------------
--
//----------------------------------------------------------------------
// Daniel Wu dan...@cs.ucsb.edu
// Dept of Computer Science, UCSB, 91306, USA
//----------------------------------------------------------------------

Jonathan Locke

unread,
Sep 23, 1996, 3:00:00 AM9/23/96
to

I'm certain you can do all these things. However, I'm not sure exactly
why you would want to track rethrow points because those stack frames
would be in the exception stack trace if you just let the exception go
all the way to the top. I'll just have to assume you have your
reasons. Anyway, here's the key to it all:

// Get stack trace from Throwable t
ByteArrayOutputStream o = new ByteArrayOutputStream();
PrintStream p = new PrintStream(o);
t.printStackTrace(p);
String strStackTrace = o.toString().trim();

I will be posting my debugging class library to
http://www.sealevelsoftware.com/sealevel/Java.html within the next 2-3
days. This code includes some of what you want to do, as well as a very
nice set of classes/methods for doing very informative code assertions.
Be aware however, that the actual format of stack trace information is
incompatible between Java VM's, so you may have to tweak the code to get
it to work... or if you are using Microsoft's jview or some other VM
that doesn't give adequate debugging information, you may simply be out
of luck completely.

J

/**
* Contract Java programmer at large (Jo...@SealevelSoftware.com)
* @param codeSpecifications Your project requirements.
* @return High quality, well documented Java code.
* @see SealevelSoftware at http://www.sealevelsoftware.com/sealevel/
*/
public JavaCode Jonathan_Locke(String codeSpecifications) { /*
Undocumented algorithm... ;-) */ }

Doug Bell

unread,
Sep 23, 1996, 3:00:00 AM9/23/96
to

dan...@cs.ucsb.edu (Daniel Wu) wrote:

> I have a couple of questions about exception handling. In my code I
> catch an exception and then rethrow it, using a different exception class:
>
> ------------------------------------------------------------
> try {
> ...
> }catch (IOException e) {
> System.out.print (e.toString() + " -- Cannot read file");
> e.printStackTrace ();
> throw new MessageException (e.toString ());
> }
> ------------------------------------------------------------

[snip]


>
> Elsewhere in the code, I catch the MessageException that was re-thrown
> earlier, and reprint the stack trace:
>
> ------------------------------------------------------------
> try {
> ...
> } catch (MessageException e) {
> e.printStackTrace ();
> throw new HORBException (e.toString ());
> }
>
> ------------------------------------------------------------

[snip]


>
> ====================================================================
> QUESTION 1: Is there any way to preserve the original line
> number the exception was triggered when propagating
> the exception?
> ====================================================================


catch (Exception e) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(baos));
throw new Exception(baos.toString());
}

This will keep save the current stack trace in the exception message. You
can cascade this as many time as you want. What you'll get is something
like:

java.lang.RuntimeException: java.lang.NullPointerException: java.lang.Exception
at A.f(Test.java:7)
at B.f(Test.java:18)
at C.f(Test.java:36)
at Test.init(Test.java:71)
at sun.applet.AppletPanel.run(AppletPanel.java:259)
at java.lang.Thread.run(Thread.java:294)

at B.f(Test.java:23)
at C.f(Test.java:36)
at Test.init(Test.java:71)
at sun.applet.AppletPanel.run(AppletPanel.java:259)
at java.lang.Thread.run(Thread.java:294)

at C.f(Test.java:41)
at Test.init(Test.java:71)
at sun.applet.AppletPanel.run(AppletPanel.java:259)
at java.lang.Thread.run(Thread.java:294)

where all the exceptions are listed in reverse order on the first line
(i.e. in the above example, java.lang.Exception was the initial exception
thrown and java.lang.RuntimeException was the last rethrow), followed by
the complete stack traces in the order they occurred.

If you want to get a little fancier, you can trim the message down so that
it only includes the stack trace up to the point that it is rethrown as a
different exception.

[snip]


> I would prefer to have the exception output formatted as:
>
> java.io.IOException: read error -- Cannot read file
> at DataStore.CmdMessage.execute(CmdMessage.java:130)
> DataStore.MessageException:
> at DataStore.DSServer.execute(DSServer.java:84)
> horb.orb.HORBException:
> at DataStore.DSServer_Skeleton.stub1001(DSServer_Skeleton.java:68)
> at DataStore.DSServer_Skeleton.dispatch(DSServer_Skeleton.java:115)
> at horb.orb.ThreadServer.MethodCallLoop(ThreadServer.java)
> at horb.orb.ThreadServer.createInstance(ThreadServer.java)
> at horb.orb.ThreadServer.run(ThreadServer.java)
>
> The line numbers under each exception would indicate where the exception
> was caught (not thrown).
>
> ====================================================================
> QUESTION 2: Is it possible to reformat the stack trace
> in this manner?
> ====================================================================


You can reformat it however you would like, complete with all the relvant
information. If you want it to look like what you have above, you will
have to write the reformatted text to System.err yourself as
printStackTrace() will always put the name of the thrown exception at the
top.

Doug Bell
db...@shvn.com

0 new messages