www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Feature idea: scope (failure,

reply Andrej Mitrovic via Digitalmars-d <digitalmars-d puremagic.com> writes:
One idea I'd like to see is to enhance scope(failure) to allow it to
catch a specific type of exception which would allow us to e.g. log
the exception message and potentially re-throw the exception. All of
this without having to nest our code in try/catch statements.

So instead of having code such as the following:

-----
void test ( )
{
    try
    {
        prepare();
        foo();
        finish();

        try
        {
            prepare();
            bar();
            finish();
        }
        catch (MyException ex)
        {
            logger.log("bar() failed with: " ~ ex.msg);
            throw ex;
        }
    }
    catch (MyException ex)
    {
        logger.log("foo() failed with: " ~ ex.msg);
        throw ex;
    }
}
-----

-----
void test ( )
{
    scope (failure, MyException ex)
    {
        logger.log("foo() failed with: " ~ ex.msg);
        throw ex;
    }

    prepare();
    foo();
    finish();

    scope (failure, MyException ex)
    {
        logger.log("bar() failed with: " ~ ex.msg);
        throw ex;
    }

    prepare();
    bar();
    finish();
}
-----

Granted it's not the best example out there, but I think it has
potential. Thoughts?
Mar 26 2015
next sibling parent reply "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Thursday, 26 March 2015 at 11:23:34 UTC, Andrej Mitrovic wrote:
 Granted it's not the best example out there, but I think it has
 potential. Thoughts?
Your example will print the exception message 2 (or 3) times. Is this really necessary? I've found that scope(failure) log("Failure while transmogrifying " ~ victim ~ ":"); is often sufficient. Assuming the exception will be caught and logged to the same output as the log line above, it'll show up right before the exception details, thus giving the needed context. What is your use case for only logging specific exception types? It would be nice if we could add arbitrary information to in-flight exceptions themselves. E.g. a nicer way to do something like this: try transmogrify(victim); catch (Exception x) { x.msg = "Failure while transmogrifying " ~ victim ~ ":\n" ~ msg; throw x; } I've also tried a different approach, using chained exceptions: https://github.com/CyberShadow/ae/blob/master/utils/exception.d#L68-L91
Mar 26 2015
parent Andrej Mitrovic via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 3/26/15, Vladimir Panteleev via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 What is your use case for only logging specific exception types?
We already have scope(failure) with its defined semantics (it will not swallow the exception), changing that would be bad. So the only workable solution I see is to extend it via 'scope(failure, ExceptionType ex)'. It's not that I want to catch specific exceptions, but instead I really love using scope but often find myself wishing I could catch the exception, swallow it (not rethrow it) and log it, without a try/catch. Sometimes you're not allowed to propagate an exception (think nothrow functions, functions that interact with C, functions invoked in different threads, etc), so you have to try/catch and use logging. I kind of think extending scope could make this nicer to work with. It was just a passing thought, though. :)
Mar 28 2015
prev sibling next sibling parent "w0rp" <devw0rp gmail.com> writes:
I think I'd tend towards not adding this feature. It seems like 
it's just a logging problem, and try-catch is probably enough for 
that.
Mar 26 2015
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2015-03-26 12:23, Andrej Mitrovic via Digitalmars-d wrote:
 One idea I'd like to see is to enhance scope(failure) to allow it to
 catch a specific type of exception which would allow us to e.g. log
 the exception message and potentially re-throw the exception. All of
 this without having to nest our code in try/catch statements.
Sounds like you want a catch statement without being tied to a try statement. Something like this exists in Ruby: With begin/end: def foo begin raise 'foo' rescue Exception => E p e end end Without: def foo raise 'foo' rescue Exception => E // tied to the function scope p e end In the above example the "rescue" is tied to the function scope. Something similar could be supported in D: void foo () { throw new Exception("foo"); catch (Exception e) // tied to the function scope writeln(e); } Or possibly tie it to the most enclosing scope: void foo () { { throw new Exception("foo"); catch (Exception e) // tied to the scope writeln(e); } } I wouldn't mind if this was supported. -- /Jacob Carlborg
Mar 27 2015