www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Disallow catch without parameter ("LastCatch")

reply grauzone <none example.net> writes:
Right now, you can catch every exception with "try { something; } catch 
{ somethingelse; }".

Can we get rid of this abomination before D2 is finalized? I claim that 
it's completely useless, and even more so, every single use of this is a 
bug.

If you really want to catch everything, you might as well write "catch 
(Exception o)", or "catch (Throwable o)" for those who know what they're 
doing.

PS: I wonder, should the runtime really execute finally blocks if an 
"Error" exception is thrown? (Errors are for runtime errors, Exception 
for normal exceptions.) Isn't it dangerous to execute arbitrary user 
code in presence of what is basically an internal error?
Oct 25 2009
next sibling parent reply Leandro Lucarella <llucax gmail.com> writes:
grauzone, el 25 de octubre a las 12:09 me escribiste:
 Right now, you can catch every exception with "try { something; }
 catch { somethingelse; }".
 
 Can we get rid of this abomination before D2 is finalized? I claim
 that it's completely useless, and even more so, every single use of
 this is a bug.
Why every use of this is a bug? -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- aFR [afr my.farts.cause.nuclear.reaction.org] has quit IRC (Ping timeout)
Oct 25 2009
parent reply grauzone <none example.net> writes:
Leandro Lucarella wrote:
 grauzone, el 25 de octubre a las 12:09 me escribiste:
 Right now, you can catch every exception with "try { something; }
 catch { somethingelse; }".

 Can we get rid of this abomination before D2 is finalized? I claim
 that it's completely useless, and even more so, every single use of
 this is a bug.
Why every use of this is a bug?
Because you most likely catch more exception types than you really want. For example, a novice programmer is likely to write something like this: int x; try { x = convert(somestring); } catch { //convert throws some exception if convert() fails return -1; } This is a bug, because catch might catch and *hide* a runtime error like failing assertions. The programmer really wanted to write "catch (ConversionException e)". Even if he wrote "catch (Exception e)", he wouldn't catch runtime errors, and the code would be safe.
Oct 26 2009
parent Leandro Lucarella <llucax gmail.com> writes:
grauzone, el 26 de octubre a las 08:44 me escribiste:
 Leandro Lucarella wrote:
grauzone, el 25 de octubre a las 12:09 me escribiste:
Right now, you can catch every exception with "try { something; }
catch { somethingelse; }".

Can we get rid of this abomination before D2 is finalized? I claim
that it's completely useless, and even more so, every single use of
this is a bug.
Why every use of this is a bug?
Because you most likely catch more exception types than you really want. For example, a novice programmer is likely to write something like this: int x; try { x = convert(somestring); } catch { //convert throws some exception if convert() fails return -1; } This is a bug, because catch might catch and *hide* a runtime error like failing assertions. The programmer really wanted to write "catch (ConversionException e)". Even if he wrote "catch (Exception e)", he wouldn't catch runtime errors, and the code would be safe.
OK, I see. What about rewriting: try { foo(); } catch { something(); } As: try { foo(); } catch (Exception) { something(); } (I mean the compiler)? I think a catch all is a nice feature for quick&dirty scripts, it would be nice to keep it and fix the semantics. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- Y cuando llegamos a nuestro hogar ella saca de su bolsillo derecho un casete de Ricardo Montaner y nos dice: "Ponelo! Ponelo!"; nos desilusionamos un poco, pero a esa altura... Todo da igual. -- Sidharta Kiwi
Oct 27 2009
prev sibling next sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
grauzone wrote:
 Right now, you can catch every exception with "try { something; } catch 
 { somethingelse; }".
 
 Can we get rid of this abomination before D2 is finalized? I claim that 
 it's completely useless, and even more so, every single use of this is a 
 bug.
 
 If you really want to catch everything, you might as well write "catch 
 (Exception o)", or "catch (Throwable o)" for those who know what they're 
 doing.
 
 PS: I wonder, should the runtime really execute finally blocks if an 
 "Error" exception is thrown? (Errors are for runtime errors, Exception 
 for normal exceptions.) Isn't it dangerous to execute arbitrary user 
 code in presence of what is basically an internal error?
Are all Errors unrecoverable except by immediately aborting the application? What about logging? What about putting up a reasonable error message for the user? What about restarting the failed module in case the issue was temporary and environmental?
Oct 25 2009
parent reply grauzone <none example.net> writes:
Christopher Wright wrote:
 PS: I wonder, should the runtime really execute finally blocks if an 
 "Error" exception is thrown? (Errors are for runtime errors, Exception 
 for normal exceptions.) Isn't it dangerous to execute arbitrary user 
 code in presence of what is basically an internal error?
Are all Errors unrecoverable except by immediately aborting the application? What about logging? What about putting up a reasonable error message for the user? What about restarting the failed module in case the issue was temporary and environmental?
Something is wrong with your program internally if something like this happens. You can't expect a consistent program state. And most of the code in finally blocks was not written for such situations. You'll probably end up throwing another runtime error from within a finally block. If you really want reliability, you should terminate the process immediately, and check the situation from another process.
Oct 26 2009
parent Christopher Wright <dhasenan gmail.com> writes:
grauzone wrote:
 Christopher Wright wrote:
Please keep full attributions.
 PS: I wonder, should the runtime really execute finally blocks if an 
 "Error" exception is thrown? (Errors are for runtime errors, 
 Exception for normal exceptions.) Isn't it dangerous to execute 
 arbitrary user code in presence of what is basically an internal error?
Are all Errors unrecoverable except by immediately aborting the application? What about logging? What about putting up a reasonable error message for the user? What about restarting the failed module in case the issue was temporary and environmental?
Something is wrong with your program internally if something like this happens. You can't expect a consistent program state. And most of the code in finally blocks was not written for such situations. You'll probably end up throwing another runtime error from within a finally block.
Quite possibly. But immediately terminating the process is simply not acceptable. How am I going to fix this problem if I can't even log that a problem occurred? If I have a SaaS application, I have to rely on my users to email or call up to find out something bad happened? What if it's an assertion error or a bounds error in a plugin? I can unload that plugin and continue on with no issues. I'm getting OutOfMemoryErrors? I'll disable caching and prefetching and reduce my memory footprint by 80%. Problem solved. There is one category of errors that is not recoverable. If the runtime is left in an inconsistent state, it should try to output an error message and terminate. Everything else, an application could potentially handle.
Oct 26 2009
prev sibling parent reply BCS <none anon.com> writes:
Hello grauzone,

 PS: I wonder, should the runtime really execute finally blocks if an
 "Error" exception is thrown? (Errors are for runtime errors, Exception
 for normal exceptions.) Isn't it dangerous to execute arbitrary user
 code in presence of what is basically an internal error?
 
If a thrown Error doesn't run finally blocks you will have a very hard time arguing for catch working and once those don't happen it might as well kill -9 the process so why even have it in the first place?
Oct 27 2009
parent reply grauzone <none example.net> writes:
BCS wrote:
 Hello grauzone,
 
 PS: I wonder, should the runtime really execute finally blocks if an
 "Error" exception is thrown? (Errors are for runtime errors, Exception
 for normal exceptions.) Isn't it dangerous to execute arbitrary user
 code in presence of what is basically an internal error?
If a thrown Error doesn't run finally blocks you will have a very hard time arguing for catch working and once those don't happen it might as well kill -9 the process so why even have it in the first place?
You still can use a "catch (Throwable t)" to catch all kinds of errors. I just think that finally (and scope(exit)) should be designed with high level code in mind. Code that allocates heap memory in a finally block is already broken (what if an out of memory error was thrown?).
Oct 27 2009
parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Wed, 28 Oct 2009 00:21:47 +0300, grauzone <none example.net> wrote:

 BCS wrote:
 Hello grauzone,

 PS: I wonder, should the runtime really execute finally blocks if an
 "Error" exception is thrown? (Errors are for runtime errors, Exception
 for normal exceptions.) Isn't it dangerous to execute arbitrary user
 code in presence of what is basically an internal error?
If a thrown Error doesn't run finally blocks you will have a very hard time arguing for catch working and once those don't happen it might as well kill -9 the process so why even have it in the first place?
You still can use a "catch (Throwable t)" to catch all kinds of errors. I just think that finally (and scope(exit)) should be designed with high level code in mind. Code that allocates heap memory in a finally block is already broken (what if an out of memory error was thrown?).
I've seen code that has throws new OutOfMemoryException(__FILE__, __LINE__); when malloc (or other allocation mechanism) has failed, and it always make me smile. QtD did just that last time I've checked.
Oct 27 2009
next sibling parent Max Samukha <spambox d-coding.com> writes:
On Wed, 28 Oct 2009 02:12:12 +0300, "Denis Koroskin"
<2korden gmail.com> wrote:

On Wed, 28 Oct 2009 00:21:47 +0300, grauzone <none example.net> wrote:

 BCS wrote:
 Hello grauzone,

 PS: I wonder, should the runtime really execute finally blocks if an
 "Error" exception is thrown? (Errors are for runtime errors, Exception
 for normal exceptions.) Isn't it dangerous to execute arbitrary user
 code in presence of what is basically an internal error?
If a thrown Error doesn't run finally blocks you will have a very hard time arguing for catch working and once those don't happen it might as well kill -9 the process so why even have it in the first place?
You still can use a "catch (Throwable t)" to catch all kinds of errors. I just think that finally (and scope(exit)) should be designed with high level code in mind. Code that allocates heap memory in a finally block is already broken (what if an out of memory error was thrown?).
I've seen code that has throws new OutOfMemoryException(__FILE__, __LINE__); when malloc (or other allocation mechanism) has failed, and it always make me smile. QtD did just that last time I've checked.
The "or other allocation mechanism" part is important. If an allocation on GC heap has failed, it doesn't make sense to allocate the exception object there. But in the case of malloc, the program may still be able to allocate the exception object and try to recover if it makes sense. So I don't think the code is all that amusing.
Oct 28 2009
prev sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
Denis Koroskin wrote:
 On Wed, 28 Oct 2009 00:21:47 +0300, grauzone <none example.net> wrote:
 
 BCS wrote:
 Hello grauzone,

 PS: I wonder, should the runtime really execute finally blocks if an
 "Error" exception is thrown? (Errors are for runtime errors, Exception
 for normal exceptions.) Isn't it dangerous to execute arbitrary user
 code in presence of what is basically an internal error?
If a thrown Error doesn't run finally blocks you will have a very hard time arguing for catch working and once those don't happen it might as well kill -9 the process so why even have it in the first place?
You still can use a "catch (Throwable t)" to catch all kinds of errors. I just think that finally (and scope(exit)) should be designed with high level code in mind. Code that allocates heap memory in a finally block is already broken (what if an out of memory error was thrown?).
I've seen code that has throws new OutOfMemoryException(__FILE__, __LINE__); when malloc (or other allocation mechanism) has failed, and it always make me smile.
Maybe the GC should reserve a small amount of space (~1KB) for its exceptions, when memory is tight.
Oct 28 2009
parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Wed, 28 Oct 2009 14:23:38 +0300, Christopher Wright  
<dhasenan gmail.com> wrote:

 Denis Koroskin wrote:
 On Wed, 28 Oct 2009 00:21:47 +0300, grauzone <none example.net> wrote:

 BCS wrote:
 Hello grauzone,

 PS: I wonder, should the runtime really execute finally blocks if an
 "Error" exception is thrown? (Errors are for runtime errors,  
 Exception
 for normal exceptions.) Isn't it dangerous to execute arbitrary user
 code in presence of what is basically an internal error?
If a thrown Error doesn't run finally blocks you will have a very hard time arguing for catch working and once those don't happen it might as well kill -9 the process so why even have it in the first place?
You still can use a "catch (Throwable t)" to catch all kinds of errors. I just think that finally (and scope(exit)) should be designed with high level code in mind. Code that allocates heap memory in a finally block is already broken (what if an out of memory error was thrown?).
I've seen code that has throws new OutOfMemoryException(__FILE__, __LINE__); when malloc (or other allocation mechanism) has failed, and it always make me smile.
Maybe the GC should reserve a small amount of space (~1KB) for its exceptions, when memory is tight.
OutOfMemory exception is supposed to be thrown with a call to onOutOfMemoryError(), that throws OutOfMemoryError.classinfo.init (i.e. global immutable instance of an Error).
Oct 28 2009
parent Christopher Wright <dhasenan gmail.com> writes:
Denis Koroskin wrote:
 OutOfMemory exception is supposed to be thrown with a call to 
 onOutOfMemoryError(), that throws OutOfMemoryError.classinfo.init (i.e. 
 global immutable instance of an Error).
That's clever. I like it.
Oct 28 2009