On Sunday, 3 August 2014 at 15:28:43 UTC, Manu via Digitalmars-d wrote:
I'm trying to make better use of scope guards, but I find myself belting
out try/catch statements almost everywhere.
I'm rather disappointed, because scope guards are advertised to offer the promise of eliminating try/catch junk throughout your code, and I'm just
not finding that to be the practical reality.

I think the core of the problem is that scope(failure) is indiscriminate, but I want to filter it for particular exceptions. The other issue is that you still need a catch() if you don't actually want the program to
terminate, which implies a try... :/

One thing that may be leveraged to eliminate most catch blocks is the existing ability to return from scope guard blocks, allowing to gracefully
return from a function while unwinding, akin to a catch.
The problem then is that you can't handle specific exceptions.

I'm thinking this would make all the difference:

scope(failure, MyException e) // only executed for exceptions of type
MyException
{
writeln(e.msg); // can refer to the exception in this failure block return failureValue; // and can gracefully return from the function too
}

That would eliminate about 80% of my try/catch blocks.

That is exactly like a catch-block.

The remaining suffer from the problem where I want to respond to exceptions NOT of a specific type, ie, clean up in the case of an unexpected/unknown
exception.

scope(failure, ~MyException)
{
  // clean up, because some unexpected exception occurred that I
don't/can't handle.
}

That I can agree would be useful, but within a catch-block instead. You can always manually check the type of the exception.

catch (Exception e)
{
    if (auto myException = cast(MyException) e)
        // handle
    else
        // cleanup
}

Of course this logic could be nicely handled with AST macros ;)

Is there already some mechanism to do this? I couldn't find anything in the
docs.
It seems like an obvious thing to want to do.

It seems like you want to have a catch-block without a try-block. I think that would be useful. A catch-block without a try-block would implicitly add a try-block to the same scope as the catch-block or to the closest function body. Ruby has this and it's quite nice.

void foo ()
{
    connectToDatabase();

    catch (DatabaseException e)
        cleanup();
}

Reply via email to