Change the name of ArrayBoundsException in druntime

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Thu Oct 23 12:44:46 PDT 2008


Steven Schveighoffer wrote:
> "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.

Sorry, I meant to catch Exception. My point was, if I want to print an 
informative message, the exception should be able to provide it without 
having to encode it in its type.

> 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());
> }

I think we're a bit too immersed in the "what can we add to the 
language". In this case, for example, I see no reason for the "if" to be 
moved inside and call it a day.


Andrei



More information about the Digitalmars-d mailing list