Multiple catch?

Hi

I would like to suggest (if this is the proper topic and/or it wasn't suggested already) the following construct:

try{

...

}catch(SomeException1, ..., SomeExceptionn e){

//treat it

}

insteed of:

try{

...

}catch(SomeException1 e){

//treat it

} ...catch (SomeExceptionn e){

//treat it in the same fashion

}

What is your oppinion?

[954 byte] By [gysz] at [2007-9-30 20:01:19]
# 1
How about:catch(MyBaseClassForFawkingExceptions ex)?
subSequence at 2007-7-7 0:47:48 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 2

Which is the Base Exception class of this two classes if you don't want to catch NullPointerException: SAXException and IOException?

And it is definitely not MyBaseClassForFawkingExceptions.

More: it is not recomended to catch Exception.

In the suggested way you can specify exactly the exceptions you want to catch, but don't need to write the same code over and over (even if this code is a one line e.printStackTrace();

gysz at 2007-7-7 0:47:48 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 3
try{//do X}catch(Exception e){if(e instanceof SAXException)doStuff();elseif(e instanceof IOException)doOtherStuff();elsethrow e;}
subSequence at 2007-7-7 0:47:48 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 4

With this you write more code than in the current method of handling exception.

My idea was to reduce code writing, and increase code readability. I think my suggestion can be easily implemented (the old version of the catch method can be generated automatically) and will achieve this goals.

By the way your code doesn't exemplify my suggestion. These version yes:

try {

//do X

} catch(Exception e) {

if(e instanceof SAXException) {

doStuff();

} else if(e instanceof IOException) {

doStuff();

} else {

throw e;

}

}

or better

try {

//do X

} catch(Exception e) {

if(e instanceof SAXException || e instanceof IOException) {

doStuff();

} else {

throw e;

}

}

Current method:

try {

//do X

} catch(SAXException e) {

doStuff();

} catch(IOException e) {

doStuff();

}

The essential change is that the same "stuff" need to be done in both cases. My code would be:

try {

//do X

} catch(SAXException, IOException e) {

doStuff();

}

Compare the readability of these versions (and think about cases when more than 2 exceptions need to be catch).

gysz at 2007-7-7 0:47:48 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 5
I don't find your version as readable as the existing mechanism.Dave.
dcminter at 2007-7-7 0:47:48 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 6

Even if I write like this?

try {

//do something

} catch (Exception1,

Exception2,

Exception3,

Exception4 e) {

doStuff();

}

However this construction usage should not be a must, only a possibility :)

gysz at 2007-7-7 0:47:48 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 7

> Even if I write like this?

Yes. Because generally well handled error code either does the same thing for all errors (in which case you're ok to catch Exception) or does different things for different exception types, in which case the existing mechanism is just fine:

tr y {

// Whatever

} catch( IOException e ) {

ioProblem(e);

} catch( ClassCastException e ) {

log.log(Level.ERROR,"Wrong type provided",e);

} catch( SQLException e ) {

sqlProblem(e);

} catch( Exception e ) {

log.log(Level.SEVERE,"Unknown problem",e);

throw new FooException("Unexpected Problem",e);

} finally {

// Tidy up.

}

In your example, I can only know that the exception I receive is of type Throwable anyway, because that's the lowest type in the hierarchy that's guaranteed to be common to the types being caught.

Dave.

dcminter at 2007-7-7 0:47:48 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 8

> Yes. Because generally well handled error code either

> does the same thing for all errors (in which case

> you're ok to catch Exception) or does different things

> for different exception types, in which case the

> existing mechanism is just fine:

For this please read my second post. My suggestion doesn't imply that you must write only one block of exceptions:

catch (Ex1, Ex2 e) {

//doit1

} catch (Ex3, Ex4 e) {

//doit2

}

> In your example, I can only know that the exception I

> receive is of type Throwable anyway, because that's

> the lowest type in the hierarchy that's guaranteed to

> be common to the types being caught.

Not quite true. You know from which set of Exception the error occures. It's true, that you can use only the base class functions in this way (I forget this drawback). This, in case of implementation, feature will give some headache to the implementors.

My first tought was to simply expand the construction to the currently used synthax (like a preprocessor) and then compile the code - so the compiler will know if you use any invalid function on one of the caught exception.

gysz at 2007-7-7 0:47:48 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 9

> For this please read my second post. My suggestion

> doesn't imply that you must write only one block of

> exceptions:

No, I realise that, but you're obliged to either handle the Throwable type, or to carry out a series of ungainly casts that might as well be written in the existing approach:

catch( Ex1, Ex2 e ) {

lt2Handler((Throwable)e); // Casts illustrative, NOT necessary

} catch( Ex3, Ex4 e ) {

gt2Handler((Throwable)e);

}

Yes that's ok, I suppose, but it doesn't really make much different. Whereas:

catch( Ex1, Ex2 e ) {

if( e instanceof Ex1) {

// Cast NECESSARY here or in called method

Ex1Handler((Ex1)e);

} else if ( e instanceof Ex2 ) {

// Cast NECESSARY here or in called method

Ex2Handler((Ex2)e);

}

// Presumably there's some generic stuff, otherwise it's a bit

// of a waste of time

lt2Handler((Throwable)e); // Cast illustrative, NOT necessary

} catch( Ex3, Ex4 e ) {

gt2Handler((Throwable)e);

}

The specific sort of thing you're probably thinking of is where we're trying to handle groups of exceptions that mean similar things - for example, when doing some SQL, the exceptions group roughly as:

* Couldn't load the driver, couldn't instantiate the driver, couldn't cast the driver.

* Couldn't setup the SQL, couldn't do the SQL

* Logic to prepare/handle the data failed.

But generally, in practice, these resolve as "Couldn't get/set the data". So you should just catch, wrap, and re-throw the exceptions for the layer above to worry about.

Your "workaround" might solve this, but it's not a very object oriented way to handle it. And really there's only a problem when you're actually using the base-class logic. For example, if I really wanted to handle the three described problem types differently, I'd probably do this:

public void doFoo()

throws MyDriverException, MyDBException, My

{

try {

// Do SQL stuff on the database

} catch( ClassNotFoundException e ) {

throw new MyDriverException("Could not load DB driver",e);

} catch( IllegalAccessException e ) {

throw new MyDriverException("Could not instantiate DB driver",e);

} catch( SQLException e ) {

throw e;

} catch( Exception e ) {

throw new MyDataException("Data problem carrying out database operation Foo",e);

} finally {

// Cleanup

}

}

// ...

try {

doFoo();

} catch( SQLException e ) {

// Handle SQL problems

} catch( DriverException e ) {

// Handle Driver problems

} catch( MyDataException e ) {

// Handle Data problems

}

dcminter at 2007-7-7 0:47:48 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 10

Yes, the approach is not object oriented, I would like to call as "macro oriented".

The value in this construction would be if you need to write several time the same code, without using the specialized exception capabilities (for example only when the e.getMessage() method to be used).

Thank you for your contributions and time. Now, I think that the solution has a limited usability - only an extra, sometimes usefull construction. Maybe this kind of functionality can be inserted (or exist already?) in a java editor.

gysz at 2007-7-7 0:47:48 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 11
It's definitely possible, but even the phrase "macro eriented" is liable to put most people off. I wouldn't have any use for it myself; if you're still enthusiastic, I'd suggest that you have a go at implementing it yourself and then see if there's any interest in the
dcminter at 2007-7-7 0:47:48 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 12

It looks neat to me, although I too can't express any need I would have found for it. If you plan to submit it to sun for consideration. The only problem I see with that is that the arg "e" is going to be of different classes, potentially, upon separate times in the catch. Thus code inside the catch would either have to provide for that by treating "e" as an Object of type Exception, or running different batches of code for different types...

Overall, I can't really see a use. I am sure, though, that you could come up with a dynamic way around your problem if it's truly that big a deal (or used more than once).

Adeodatus at 2007-7-7 0:47:48 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 13

Really I don't understand why you guys are grilling this guy so much. This is not the first time I've heard someone suggest this feature, and I personally would find it very useful.

I rather frequently find myself wanting to catch a small number of very specific exceptions and handling them in the same way. Furthermore, I typically don't want to use a superclass in the catch expression because: (1) there are other subclasses of the superclass which I do not want to catch; and (2) spelling out which exceptions are being caught is a form of self-documentation (if you just catch "Exception", the reader has no idea about what you intended to catch, or even which exceptions are possible without poking around a bit). In these cases, I end up writing two catch (or more) catch blocks which contain the exact same code. That's more to read, more to maintain, and more opportunity to make mistakes.

As far as which class "e" would resolve to, I recall that someone suggested in a previous thread to use the most specific, common superclass.

Jim

JN_ at 2007-7-7 0:47:48 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 14
> Thus code inside the catch would either> have to provide for that by treating "e" as an Object> of type Exception, or running different batches of> code for different types...Throwable actually, not Exception. See discussion above?Dave.
dcminter at 2007-7-7 0:47:48 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 15

> Really I don't understand why you guys are grilling

> this guy so much.

This is me being outstandingly polite and respectful. Normally I spit on the graves of people posting in the JCP forum, usually because their suggestions are either impossible or unwise. This one is at least coherent and possible, if still (in my opinion) not a great idea.

> I rather frequently find myself wanting to catch a

> small number of very specific exceptions and handling

> them in the same way.

If they're your exception classes, that indicates that they should be implementing a common interface. If not, well, I'm afraid it's just tough at the moment. I don't personally consider it worth the effort given that you'll have to handle Throwable references instead of the actual exception types, and that takes away most of the advantages of the proposal.

I really dislike the suggestion that a "macro" style approach should be used to allow you to call the normal range of methods, because it's a horrendous special case to tackle a very minor issue. It seriously breaks the principle of least surprise.

> Furthermore, I typically don't

> want to use a superclass in the catch expression

> because: (1) there are other subclasses of the

> superclass which I do not want to catch; and

Then wrap and re-throw your exceptions.

> (2)

> spelling out which exceptions are being caught is a

> form of self-documentation (if you just catch

> "Exception", the reader has no idea about what you

> intended to catch, or even which exceptions are

> possible without poking around a bit).

Minor point, vaguely in favour of the approach suggested, but frankly if they're all inheriting from something slightly more precise than Exception, I don't see the problem with catching them under that banner heading.

> In these

> cases, I end up writing two catch (or more) catch

> blocks which contain the exact same code. That's more

> to read, more to maintain, and more opportunity to

> make mistakes.

Invoke a handler. Or use a closure and wrapped/rethrown exceptions to achieve the desired result.

> As far as which class "e" would resolve to, I recall

> that someone suggested in a previous thread to use the

> most specific, common superclass.

If that exists, the problem goes away for most people's purposes anyway.

The suggestion is syntactic sugar. If it could be implemented clearly and simply, I'd probably be grudgingly for it. Since it can't, I'm not. If you like it so much, write it and see if people go for it. If you can't or won't, nobody is going to do it for you.

Dave.

dcmintera at 2007-7-19 23:50:23 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 16

> The suggestion is syntactic sugar. If it could be

> implemented clearly and simply, I'd probably be

> grudgingly for it. Since it can't, I'm not. If you

> like it so much, write it and see if people go for it.

> If you can't or won't, nobody is going to do it for

> you.

Yes this is indeed a syntactic sugar (it is intended to be this). It doesn't gives any new benefits to the current syntax (but takes away a bit from the programmers possibilities). I wasn't convinced throughly that this is not a good idea. (It's a liberty of a person to use sugar in his/her tea.) Most of the ideas were explained well by Jim also.

May I ask how can somebody extend the syntax of the java language? Or Have you any ideea how to write this extension without rewriting the java compiler?

gysza at 2007-7-19 23:50:23 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 17

You could probably do something with a pre-processor. Read through the input java file, spot instances of the new catch blocks, translate them to old-style catch blocks, and spit out the updated version. That wouldn't be too hard.

catch( Ex1, Ex2, Ex3, Ex4 e ) {

e.printStackTrace();

}

Would expand to:

catch( Ex1 e ) {

e.printStackTrace();

} catch( Ex2 e ) {

e.printStackTrace();

} catch( Ex3 e ) {

e.printStackTrace();

} catch( Ex4 e ) {

e.printStackTrace();

}

That's probably good enough for a proof of concept - but it's a bit messy. Alternatively if you want to go for something a bit more sophisticated, you could look into [url https://javacc.dev.java.net/]javacc[/url], [url http://jakarta.apache.org/bcel/]BCEL[/url] and the [url http://eclipse.org/]Eclipse[/url] JDT project's embedded compiler.

Good luck with that.

dcmintera at 2007-7-19 23:50:23 > top of Java-index,Other Topics,Java Community Process (JCP) Program...
# 18

Yes, I was thinking on this solution. It's not so hard to implement. Maybe I can create a plug-in for Eclipse and/or NetBeans for this. (However I have no experiente in this. Also the time is a problem.)

Thank you once more for your comments and suggestions.

In my view of point the thread achieved it's goals.

Now I can see not only the possibilities but also the drawbacks of this construction.

gysza at 2007-7-19 23:50:23 > top of Java-index,Other Topics,Java Community Process (JCP) Program...