Please consider the following program:
import std.stdio;

struct A {
    int opApply( scope int delegate(int) dg ) {
        foreach(int i; 0 .. 50) {
            try {
                int res = dg(i);
                if( res!=0 ) {
                    writefln("Delegate returned %s", res);
                    return res;
                }
            } catch(Exception ex) {
                writefln("Caught in loop: %s", ex.msg);
            }
        }

        return 0;
    }
}

void main() {
    try {
        A a;
        foreach(i; a) {
            writefln("Loop got %s", i);

            if( i==10 ) {
                throw new Exception("Excccption");
            }

            if( i==20 ) {
                break;
            }
        }
    } catch( Exception ex ) {
        writefln("Caught outside of loop: %s", ex.msg);
    }
}

When run, I expected the loop to break after 10 iterations due to the exception being thrown. Instead, the loop continued.

The problem with this is that, sometimes, the task generating the loop might, itself, require exception handling. Distinguishing between the exceptions thrown inside the delegate and outside it becomes a somewhat tricky exercise.

At the very least, I think this behaviour should be documented.

Thoughts?

Shachar

Reply via email to