Change the name of ArrayBoundsException in druntime

Steven Schveighoffer schveiguy at yahoo.com
Thu Oct 23 12:32:15 PDT 2008


"Andrei Alexandrescu" wrote
> Sean Kelly wrote:
>> Andrei Alexandrescu wrote:
>>> Robert Fraser wrote:
>>>>
>>>> Option B:
>>>> ---------
>>>> try
>>>> {
>>>>     new Socket(30587);
>>>> }
>>>> catch(Exception e)
>>>> {
>>>>     if(e.type == ExceptionType.Socket)
>>>>         printf("Could not open socket\n");
>>>>     else
>>>>         throw e;
>>>> }
>>>
>>> I think you'd be hard-pressed to justify the "if" inside the second 
>>> example. You couldn't create a Socket, period. It doesn't matter where 
>>> exactly the exception was generated from.
>>>
>>> That's one thing about large exception hierarchies: everybody can come 
>>> with cute examples on how they could be useful. As soon as the rubber 
>>> hits the road, however, differentiating exceptions by type becomes 
>>> useless.
>>
>> It may be different in a user application, but in services it's fairly 
>> common to have specialized code for handling different exception types. 
>> And more importantly, it's common to want different exception types to 
>> propagate to different levels for handling.  Sure, one could use a 
>> generic exception handler at each level that rethrows if the detected 
>> type isn't one that handler cares about but why do this when filtering on 
>> type is a language feature?
>>
>> For example, let's say I have a network service that's backed by a SQL 
>> database.  My main program loop may look something like this:
>>
>>     bool connected = false;
>>     while( true )
>>     {
>>         try
>>         {
>>             while( true )
>>             {
>>                 auto r = acceptRequest();
>>                 scope(failure) r.tellFailed();
>>                 if( !connected )
>>                     connectToDB();
>>                 handleRequest( r );
>>             }
>>         }
>>         catch( SqlException e )
>>         {
>>             connected = false;
>>             log( e );
>>         }
>>         catch( Exception e )
>>         {
>>             log( e );
>>         }
>>     }
>>
>>     ...
>>
>>     void handleRequest( Request r )
>>     {
>>         scope(failure) r.tellFailed( "General error" );
>>
>>         try
>>         {
>>             // process r
>>         }
>>         catch( AuthException e )
>>         {
>>             r.tellFailed( "Authentication failure" );
>>         }
>>         catch( ValidationException e )
>>         {
>>             r.tellFailed( "Invalid request format" );
>>         }
>>     }
>>
>> Being able to trap specific types of exceptions makes this code cleaner 
>> and more succinct than it would be otherwise.  If this weren't possible 
>> I'd have to trap, check, and rethrow certain exceptions at different 
>> levels to ensure that the proper handler saw them.
>
> Thanks for fueling my argument. There's duplication in code examples, as 
> in many other examples I've seen in favor of by-type handling.
>
> First example:
>
>         catch( Exception e )
>         {
>             if (e.origin = "sql") connected = false;
>             log( e );
>         }
>
> Less code and no duplication. Second example is even starker:
>
>         catch( AuthException e )
>         {
>             r.tellFailed( e.toString );
>         }
>
> Clearly the need is to factor in the message to print in the exception, at 
> least in this case and many like it.

For the second example, you are assuming that ValidationException is a 
subclass of AuthException.

I think in this case, ValidationException and AuthException might share a 
common parent (SqlException) which you do NOT want to catch.  It is 
advantageous in this case to have both a hierarchy through inheritance and a 
hierarchy through parameters.

Here's another idea, to avoid rethrows, what about some pre-handler code 
that tests if an exception is what you want?  Perhaps the same mechanism 
that is used by template constraints:

catch(SqlException e) if (e.reason is Auth || e.reason is Validation)
{
   r.tellFailed(e.toString());
}

That gives you the same mechanism used with typing and without the rethrows, 
without creating N subclasses of SqlException, and without multiple 
repetitive blocks that do the same thing.  It looks more readable to me too.

Not sure how exception code works, so I don't know how plausible this is.

-Steve 





More information about the Digitalmars-d mailing list