www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - catch/rethrow

reply Sean Kelly <sean f4.ca> writes:
In C++ if I want to catch and rethrow any exception I can do this:

   try {

   } catch(...) {
     throw;
   }

The roughly equivalent syntax in D would be this:

   try {

   } catch {
     throw;
   }

But currently, 'throw' must be followed by an expression in D.  This works:

   try {

   } catch(Object o) {
     throw o;
   }

But it relies on undocumented (I believe) knowledge that all exceptions 
in D are objects and also subverts the need for a LastCatch statement. 
Is there any D equivalent of the C++ code above, barring the use of 
scope(failure)?  And why is there no way to rethrow the exception caught 
by a LastCatch statement?


Sean
Jun 07 2006
next sibling parent James Pelcis <jpelcis gmail.com> writes:
The reason Object works is because the definition of Exception is

class Exception : Object
{
// blah
}

You can use

catch (Exception o) {
	throw o;
}

or

catch (Object o) {
	throw o;
}

or just not catch it at all.

Sean Kelly wrote:
 In C++ if I want to catch and rethrow any exception I can do this:
 
   try {
 
   } catch(...) {
     throw;
   }
 
 The roughly equivalent syntax in D would be this:
 
   try {
 
   } catch {
     throw;
   }
 
 But currently, 'throw' must be followed by an expression in D.  This works:
 
   try {
 
   } catch(Object o) {
     throw o;
   }
 
 But it relies on undocumented (I believe) knowledge that all exceptions 
 in D are objects and also subverts the need for a LastCatch statement. 
 Is there any D equivalent of the C++ code above, barring the use of 
 scope(failure)?  And why is there no way to rethrow the exception caught 
 by a LastCatch statement?
 
 
 Sean

Jun 07 2006
prev sibling next sibling parent Gregor Richards <Richards codu.org> writes:
Sean Kelly wrote:
 But it relies on undocumented (I believe) knowledge that all exceptions 
 in D are objects

the fact that you can only throw things derived from Object is implicit in the structure of the language. - Gregor Richards
Jun 07 2006
prev sibling parent reply Johan Granberg <lijat.meREM OVEgmail.com> writes:
Sean Kelly wrote:
 But it relies on undocumented (I believe) knowledge that all exceptions 
 in D are objects 
 ...
 Sean

quote from the specification (statements throw) "Expression is evaluated and must be an Object reference. The Object reference is thrown as an exception." So it is documented that Exceptions is objects.
Jun 07 2006
parent reply Sean Kelly <sean f4.ca> writes:
Johan Granberg wrote:
 Sean Kelly wrote:
 But it relies on undocumented (I believe) knowledge that all 
 exceptions in D are objects ...
 Sean

quote from the specification (statements throw) "Expression is evaluated and must be an Object reference. The Object reference is thrown as an exception." So it is documented that Exceptions is objects.

Ah, good to know. But then what is the purpose of catch{}? Without the ability to rethrow, it seems to have marginal utility. Sean
Jun 07 2006
next sibling parent reply James Pelcis <jpelcis gmail.com> writes:
The purpose is to inform the user that there has been an error without 
overly interrupting the program.  I think the rationale is that after 
you have taken the time to handle an exception, why would you rethrow it?

If you disagree, you don't need to have the kind of catch.  You can 
always catch either Exception or Object and ignore the LastCatch.

Sean Kelly wrote:
 Johan Granberg wrote:
 Sean Kelly wrote:
 But it relies on undocumented (I believe) knowledge that all 
 exceptions in D are objects ...
 Sean

quote from the specification (statements throw) "Expression is evaluated and must be an Object reference. The Object reference is thrown as an exception." So it is documented that Exceptions is objects.

Ah, good to know. But then what is the purpose of catch{}? Without the ability to rethrow, it seems to have marginal utility. Sean

Jun 07 2006
next sibling parent reply Sean Kelly <sean f4.ca> writes:
But then why have catch{} at all?  It's actually less useful than 
catch(Object) as it provides no facility to rethrow the exception, and 
it offers nothing over catch(Object) in what it can catch.  Also, it's 
possible that a LastCatch block may simply be intended to detect a 
failure condition and perform some operation (similar to stack(failure)) 
or that it may need to rethrow the exception if some global condition 
cannot be met.  Sure, you could use catch(Object) in these instances, 
but then again, what is the purpose of catch{}?  Surely it can't simply 
be to avoid typing "(Object o)"?

James Pelcis wrote:
 The purpose is to inform the user that there has been an error without 
 overly interrupting the program.  I think the rationale is that after 
 you have taken the time to handle an exception, why would you rethrow it?
 
 If you disagree, you don't need to have the kind of catch.  You can 
 always catch either Exception or Object and ignore the LastCatch.
 
 Sean Kelly wrote:
 Johan Granberg wrote:
 Sean Kelly wrote:
 But it relies on undocumented (I believe) knowledge that all 
 exceptions in D are objects ...
 Sean

quote from the specification (statements throw) "Expression is evaluated and must be an Object reference. The Object reference is thrown as an exception." So it is documented that Exceptions is objects.

Ah, good to know. But then what is the purpose of catch{}? Without the ability to rethrow, it seems to have marginal utility. Sean


Jun 07 2006
parent James Pelcis <jpelcis gmail.com> writes:
I can't say for sure, but I think one of the uses of a LastCatch instead 
of catch (Object) is efficiency of the compiled code.  It knows that the 
code should be called without worrying about if it meets some criteria. 
  Essentially, I believe it's for optimization when all you need to know 
is that something went wrong.

Of course, I could be totally wrong.  If so, I agree that it serves no 
purpose and should be removed or deprecated.

Sean Kelly wrote:
 But then why have catch{} at all?  It's actually less useful than 
 catch(Object) as it provides no facility to rethrow the exception, and 
 it offers nothing over catch(Object) in what it can catch.  Also, it's 
 possible that a LastCatch block may simply be intended to detect a 
 failure condition and perform some operation (similar to stack(failure)) 
 or that it may need to rethrow the exception if some global condition 
 cannot be met.  Sure, you could use catch(Object) in these instances, 
 but then again, what is the purpose of catch{}?  Surely it can't simply 
 be to avoid typing "(Object o)"?
 
 James Pelcis wrote:
 The purpose is to inform the user that there has been an error without 
 overly interrupting the program.  I think the rationale is that after 
 you have taken the time to handle an exception, why would you rethrow it?

 If you disagree, you don't need to have the kind of catch.  You can 
 always catch either Exception or Object and ignore the LastCatch.

 Sean Kelly wrote:
 Johan Granberg wrote:
 Sean Kelly wrote:
 But it relies on undocumented (I believe) knowledge that all 
 exceptions in D are objects ...
 Sean

quote from the specification (statements throw) "Expression is evaluated and must be an Object reference. The Object reference is thrown as an exception." So it is documented that Exceptions is objects.

Ah, good to know. But then what is the purpose of catch{}? Without the ability to rethrow, it seems to have marginal utility. Sean



Jun 07 2006
prev sibling parent =?ISO-8859-1?Q?Julio_C=E9sar_Carrascal?= <jcesar phreaker.net> writes:
James Pelcis wrote:
 overly interrupting the program.  I think the rationale is that after 
 you have taken the time to handle an exception, why would you rethrow it?

This is very common: connection.open(); try { // ... } catch { connection.close(); throw; } Of course, I could replace that with the on_scope keyword.
Jun 08 2006
prev sibling parent reply kris <foo bar.com> writes:
Sean Kelly wrote:
 Johan Granberg wrote:
 
 Sean Kelly wrote:

 But it relies on undocumented (I believe) knowledge that all 
 exceptions in D are objects ...
 Sean

quote from the specification (statements throw) "Expression is evaluated and must be an Object reference. The Object reference is thrown as an exception." So it is documented that Exceptions is objects.

Ah, good to know. But then what is the purpose of catch{}? Without the ability to rethrow, it seems to have marginal utility.

Sean; I thought you could rethrow: catch (Exception e) throw e;
Jun 07 2006
parent reply Sean Kelly <sean f4.ca> writes:
kris wrote:
 Sean Kelly wrote:
 Johan Granberg wrote:

 Sean Kelly wrote:

 But it relies on undocumented (I believe) knowledge that all 
 exceptions in D are objects ...
 Sean

quote from the specification (statements throw) "Expression is evaluated and must be an Object reference. The Object reference is thrown as an exception." So it is documented that Exceptions is objects.

Ah, good to know. But then what is the purpose of catch{}? Without the ability to rethrow, it seems to have marginal utility.

Sean; I thought you could rethrow: catch (Exception e) throw e;

You can for the above case. But D also supports: catch{ ... } ie. without the "(Exception e)". However, unlike C++, "throw;" in this instance is invalid so there's no way to rethrow the exception. Basically, I'm wondering why this form of catch exists. It can catch exceptions but not report anything about them (as it has no object reference), and it can't rethrow them. I can't think of a single case where I would actually use this statement as it exists now. Sean
Jun 07 2006
parent reply kris <foo bar.com> writes:
Sean Kelly wrote:
 You can for the above case.  But D also supports:
 
     catch{ ... }
 
 ie. without the "(Exception e)".  However, unlike C++, "throw;" in this 
 instance is invalid so there's no way to rethrow the exception.
 
 Basically, I'm wondering why this form of catch exists.  It can catch 
 exceptions but not report anything about them (as it has no object 
 reference), and it can't rethrow them.  I can't think of a single case 
 where I would actually use this statement as it exists now.

Gotcha, and neither can I
Jun 07 2006
parent Derek Parnell <derek psych.ward> writes:
On Wed, 07 Jun 2006 17:50:09 -0700, kris wrote:

 Sean Kelly wrote:
 You can for the above case.  But D also supports:
 
     catch{ ... }
 
 ie. without the "(Exception e)".  However, unlike C++, "throw;" in this 
 instance is invalid so there's no way to rethrow the exception.
 
 Basically, I'm wondering why this form of catch exists.  It can catch 
 exceptions but not report anything about them (as it has no object 
 reference), and it can't rethrow them.  I can't think of a single case 
 where I would actually use this statement as it exists now.

Gotcha, and neither can I

I have this routine that I use ... bool FileExists(char[] pFileName) { if (pFileName in lExistingFiles) { return true; } try { if(std.file.isfile(pFileName) && std.file.exists(pFileName)) { lExistingFiles[pFileName] = true; return true; } } catch { }; return false; } The idea being that I really don't care what exception is thrown by the called functions 'isfile' and 'exists', but if any exception is thrown then I want to prevent the program from crashing and also inform my caller about the information they requested - namely that the file specified doesn't exist. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 8/06/2006 11:01:06 AM
Jun 07 2006