On Saturday, March 10, 2012 17:03:43 Jacob Carlborg wrote: > On 2012-03-09 20:06, Jonathan M Davis wrote: > > In what way? Yes, they're _catchable_, but everything that was on the > > unwound portion of the stack is now in an undefined state. So, recovering > > from the AssertError and continuing execution doesn't work. So, a handler > > can catch the AssertError and do something before letting it kill the > > program, but portions of the program are definitely in an undefined state > > when an AssertError is caught. The closer the catch point is to the throw > > point, the less of an issue that is, but unless you can guarantee that no > > destructors, scope statements, or finally blocks were between the throw > > point and the catch point, then some portion of the program is in an > > undefined state, and continuing program execution is a bad idea. It _is_ > > possible to catch an AssertError, but you have to be very careful about > > what you do after that. > > > > I'm not aware of anything in contracts which would involve catching an > > AssertError and then continuing execution. When a contract fails, it's > > going to kill the program just like any other assertion failure does. So, > > I'm not quite sure what you're referring to. > > > > - Jonathan M Davis > > This might be how it works today, but I think it's a broken design. > AssertError MUST be SAFELY catchable to be able to write unit testing > frameworks.
I honestly don't think that Walter even considered unit testing frameworks when he came up with the design. He built unit tests into the language. So, from his point of view, why would you need a unit testing framework? He probably didn't even consider it. And AssertErrors _are_ catchable. You just have to deal with the fact that destructors, scope statements, and finally blocks all get skipped by them. So, cleanup doesn't tend to happen in their presence. That's more of an issue with a general unit testing framework than it would be if you were doing it closer to the throw point, but it doesn't necessarily make it so that the unit test framework doesn't work. It _does_ risk making it flakier though. What would be particularly risky is trying to continue a particular unit test block after a failed assertion, since the failures wouldn't be isolated (though personally, I think that that would be a bad idea even AssertErrors _didn't_ skip anything, simply because the failures aren't isolated, and you get a bunch of failures simply because you already had one). Running subsequent unittest blocks should be less risky (though not necessarily without risk), because unittest blocks are normally isolated. Regardless, if you don't like the fact that there's no guarantee that AssertErrors execute finally blocks, scope statements, and destructors, take it up with Walter. I'm just pointing out what the design is. I didn't make the decision - though in general, I do think that it was the correct one. It's just that there are a few cases (e.g. some unit testing stuff) where it can become an issue. And if you really want to do your own unit testing framework, maybe you should just create your own custom assertion functions which throw something other than AssertError - though if they don't throw Errors, then any unittest blocks with a catch(Exception() {} in them may not work properly, so that's not necessarily all that great a solution either, depending. - Jonathan M Davis