What should happen when the assert message expression throws?

Ali Çehreli acehreli at yahoo.com
Sun Nov 20 18:30:00 UTC 2022


On 11/19/22 00:11, Dukc wrote:

 > In my opinion the fix is clear.
[...]
 > Should the error generation exception be the `.next` member of
 > `AssertError`? Probably, but I'm not sure.

I think the following is what you describe:

import std;

void assertImpl_(string file = __FILE__, size_t line = __LINE__)(bool 
value, lazy string msgGen) {
     if (!value) {
         string msg;
         Throwable next;

         try {
             msg = msgGen;

         } catch (Exception exc) {
             msg = "(Additionally failed to generate the assertion 
failure message.)";
             next = exc;
         }

         import core.exception : AssertError;
         throw new AssertError(msg, file, line, next);
     }
}

void main() {
     // This passes through despite the error in the message:
     assertImpl_(true, format("%s"));

     // This throws AssertError where the message formatting
     // is a collateral Throwable:
     assertImpl_(false, format("%s"));
}

Discussion: As I commented on the bug report as well, D is already in 
the best-effort business when it comes to Errors:

1) If the assert expression *will* fail, the program is already in an 
invalid state. (I claim, it is not a failed assert expression that puts 
the program into invalid state; rather, the fact that the expression 
will fail.)

So, even evaluating the assert expression is best-effort.

2) The default behavior for the main thread is to catch Error and dump 
backtrace to stderr. That is best-effort because now we are catching an 
Error.

Given the above two observations, the code inside 'if (!value)' above 
should also be considered best-effort and I think is the solution for 
this bug.

The only thing that bothers me is the 'lazy' parameter which I think is 
a 'delegate'. Perhaps the compiler can use a 'function' lazily there. (?)

Ali



More information about the Digitalmars-d mailing list