Let's improve D's exceptions

Atila Neves via Digitalmars-d digitalmars-d at puremagic.com
Mon May 18 05:20:24 PDT 2015


One thing I like about `enforce` is that the program's run-time 
checks become positive instead of negative statements which I 
think is a lot more readable. i.e.

     enforce(foo && bar > 4, "...");

instead of

    if(!foo || bar <=3) throw new Exception("...");

I agree with Adam that importing `std.conv` everytime for `text` 
is annoying, as is the whole subclassing and forwarding 
constructor parameters.

Atila

On Wednesday, 13 May 2015 at 22:55:22 UTC, Steven Schveighoffer 
wrote:
> On 5/13/15 3:24 PM, Jacob Carlborg wrote:
>> On 2015-05-13 17:08, Adam D. Ruppe wrote:
>>> Have you ever done:
>>>
>>> if(something) {
>>>    import std.conv;
>>>    throw new Exception("some error " ~ to!string(some_value));
>>> }
>>>
>>> Don't you hate it?
>>>
>>> * having to import std.conv to see data from your exception 
>>> is a pain
>>> * it allocates eagerly and thus isn't suitable for a lot of 
>>> places
>>> * inspecting the data can be a pain as the string is 
>>> unstructured
>>>
>>> This assumes the data is even bothered to be added. Anyone 
>>> who has
>>> gotten a RangeError in D knows important information is often 
>>> just
>>> dropped!
>>>
>>> A good solution is to make a new exception subclass for each 
>>> error type,
>>> storing details as data members. However, that's a bit of a 
>>> pain in D
>>> because of all the work you have to do to make a complete 
>>> subclass:
>>
>> Yeah, I really hate that people are using plain Exception 
>> instead of
>> creating a subclass. I'm trying to point this out in pull 
>> requests and
>> similar but it's hard to get people to listen.
>>
>> One thing that is _not_ making things better is "enforce" 
>> which, if I
>> recall correctly, throws Exception by default.
>
> enforce is one of the most needless pieces of phobos:
>
> enforce(cond, message);
> vs.
> if(!cond) throw new Exception(message);
>
> And the second doesn't mess up inlining.
>
> I think enforce could be boiler-plated better. The only verbose 
> part of the if version is the throwing and newing.
>
> template throe(Etype = Exception)
> {
>    void throe(Args...)(Args args, string file = __FILE__, 
> size_t line = __LINE__)
>    {
>    	throw new Etype(args, file, line);
>    }
> }
>
> if(!cond) throe(message);
>
> Wait, you're in an io package, and you want to always throw IO 
> exceptions?
>
> alias except = throe!IOException;
>
> if(!cond) except(args, to, ioexception);
>
> Sure, it doesn't return the thing that caused the exception if 
> nothing happens. Grepping phobos, this feature is used with 
> enforce about 1% of the time. In fact, I didn't even know it 
> had that feature until looking it up in the docs just now.
>
> -Steve



More information about the Digitalmars-d mailing list