The Right Approach to Exceptions

Juan Manuel Cabo juanmanuel.cabo at gmail.com
Mon Feb 20 11:48:37 PST 2012


> That wouldn't work, because you'll erase the stacktrace.
>
> Plus, you are confusing inheritance with composition here. What you want is throw a COMException and link it to the
> original Exception. You have to consider Exception as a linkedlist, one being the cause of another.

You are correct. But it doesn't change the FILE and LINE attributes of the exception.
The code below changes the msg of the exception and rethrows it.
Please note that the stacktrace is changed as you say. But the:
       object.Exception at t.d(17): another
points to the site where it was produced originally:

#!/usr/bin/rdmd
import std.stdio;
void main () {
    anotherFunc();
}
void anotherFunc() {
    try {
        writeln("another func");
        badfunc();
    } catch (Exception ex) {
        ex.msg = "another";
        throw ex;
    }
}
void badfunc() {
    writeln("bad func");
    throw new Exception("badfunc");
}


another func
bad func
object.Exception at t.d(17): another
----------------
./t(void t.anotherFunc()+0x2b) [0x42a1c7]
./t(_Dmain+0x9) [0x42a195]
./t(extern (C) int rt.dmain2.main(int, char**).void runMain()+0x17) [0x43c003]
./t(extern (C) int rt.dmain2.main(int, char**).void tryExec(scope void delegate())+0x2a) [0x43b97a]
./t(extern (C) int rt.dmain2.main(int, char**).void runAll()+0x42) [0x43c056]
./t(extern (C) int rt.dmain2.main(int, char**).void tryExec(scope void delegate())+0x2a) [0x43b97a]
./t(main+0xd3) [0x43b90b]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xff) [0x7fc83b628eff]
----------------






On 02/20/2012 04:44 PM, deadalnix wrote:
> Le 20/02/2012 20:32, Juan Manuel Cabo a écrit :
>> So, if your boss wants the URL of the request that was made
>> when the standard library threw you a FileNotFoundException,
>> you can do:
>>
>>
>>     try {
>>           ...
>>          } catch (Exception ex) {
>>                  //Rethrow the exception with the added detail:
>>         ex.details["custom_url"] = getenv("URI");
>>                  throw ex;
>>          }
>>
>> (don't beat me if URI wasn't the envvar that apache sends for uri, I
>> don't remember it at the moment).
>>
>> --jm
>>
>>
>>
>> On 02/20/2012 04:27 PM, Juan Manuel Cabo wrote:
>>>> And so variant is the way to go ?
>>>>
>>>> Clearly, this is a very strong arguement in favor of typed Exception, that provide usefull information about what went
>>>> wrong. This is a safe approach.
>>>>
>>>> Because this Variant stuff is going to require massive ducktyping of Exceptions, with all possible errors involved. The
>>>> keys in the Variant[string] will depend on the Exception the dev is facing. This should be avoided and should warn us
>>>> about the requirement of typed Exceptions.
>>>
>>>
>>> Some of the things that characterize an exception, their traits, are
>>> transversal to any hierachy that you can imagine, now and in the future.
>>>
>>> You can choose to keep changing a hierarchy, or build in some mechanism
>>> to the Exception base class, that will allow you to get your traits
>>> without downcasting.
>>>
>>> Say that at your place of work the boss decides that all exception classes
>>> should have a COM error code, or that all exception classes should
>>> provide the URL of the request that generated it.
>>>
>>> You know what will happen?
>>>
>>> Your boss will require you to derive all your exception classes from
>>> COMException or from WebRequestException and then redefine FileNotFound
>>> as a subclass of them. So you will have your FileNotFoundException
>>> different than the standard library exception.
>>>
>>> Don't believe me? It happened to .NET... they've got a COMException
>>> that wraps any other kind of error during a COM call.
>>>
>>>
>>> --jm
>>>
>>


More information about the Digitalmars-d mailing list