[Issue 17226] Exception during the generation of an assert message hides AssertError

2023-02-03 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17226

Salih Dincer  changed:

   What|Removed |Added

 CC||sali...@hotmail.com

--- Comment #13 from Salih Dincer  ---
(In reply to Steven Schveighoffer from comment #12)
> What about creating a wrapper for format:
> 
> ```d
> string assertFormat(Args...)(string fmt, Args args)
> {
>try {
>  return format(fmt, args);
>} catch(Exception ex) {
>  return "Error while evaluating assert message: " ~ ex.toString;
>}
> }
> 
> 
> // use like
> assert(i == 42, assertFormat("Something %s", functionThatThrows()));
> ```
> 
> This solves the problem, and also doesn't throw away any information. Plus
> it's not unpleasant to use.
> 
> Yes, it's opt in. So what? It can just be a best practice recommendation.

alias format = assertFormat; /*
import std.format;//*/

auto foo(T)(T P) {
  //assert(P == 43, format("T: %s", T.stringof));/*
  static assert(is(T == uint), format("T:", "int"));//*/
}

> onlineapp.d(6): Error: static assert:  "Error while evaluating assert 
> message: 
> FormatException@/dlang/dmd/linux/bin64/../../src/phobos/std/format/package.d(785):
>  Orphan format arguments: args[0..1]"
> onlineapp.d(13):instantiated from here: `foo!int`

I think the problem is also with static. Because above is static assert I got
at compile time.  But I got such 4 errors message with the following library
possibilities (without assertFormat):

> /dlang/dmd/linux/bin64/../../src/phobos/std/exception.d(518): Error: uncaught 
> CTFE exception `std.format.FormatException("Orphan format arguments: 
> args[0..1]")`
> onlineapp.d(6):called from here: `format("T:", "int")`
> onlineapp.d(6): Error: static assert:  __error
> onlineapp.d(13):instantiated from here: `foo!int`


//alias format = assertFormat; /*
import std.format;//*/

auto foo(T)(T P) {
  //assert(P == 43, format("T: %s", T.stringof));/*
  static assert(is(T == uint), format("T:", "int"));//*/
}

import std.stdio;
void main() {
  enum char D = 68;
  assertFormat("Hello %s and World", D).writeln;
  foo!int(42);
}
string assertFormat(Args...)(string fmt, Args args)
{
  import std.format : _format = format;
  try
  {
return _format(fmt, args);
  }
  catch(Exception ex)
  {
enum m = "Error while evaluating assert message: ";
return m ~ ex.toString;
  }
}

SDB@79

--


[Issue 17226] Exception during the generation of an assert message hides AssertError

2022-12-17 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17226

Iain Buclaw  changed:

   What|Removed |Added

   Priority|P1  |P2

--


[Issue 17226] Exception during the generation of an assert message hides AssertError

2022-12-08 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17226

Steven Schveighoffer  changed:

   What|Removed |Added

 CC||schvei...@gmail.com

--- Comment #12 from Steven Schveighoffer  ---
What about creating a wrapper for format:

```d
string assertFormat(Args...)(string fmt, Args args)
{
   try {
 return format(fmt, args);
   } catch(Exception ex) {
 return "Error while evaluating assert message: " ~ ex.toString;
   }
}


// use like
assert(i == 42, assertFormat("Something %s", functionThatThrows()));
```

This solves the problem, and also doesn't throw away any information. Plus it's
not unpleasant to use.

Yes, it's opt in. So what? It can just be a best practice recommendation.

--


[Issue 17226] Exception during the generation of an assert message hides AssertError

2022-11-23 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17226

Bolpat  changed:

   What|Removed |Added

 CC||qs.il.paperi...@gmail.com

--- Comment #11 from Bolpat  ---
As Timon pointed out, requiring the evaluation of the assert msg to be nothrow
is a limitation, I don’t think it is a major limitation. `assumeWontThrow` [1]
is well-suited for this purpose.

I don’t think that
```d
import std.exception : assumeWontThrow;
assert(condition, assumeWontThrow(potentially throwing expr));
```
is too much to ask for. It documents clearly that the message-generating
expression could throw. That way, an Exception thrown by the message-generating
expression does not hide a bug.

[1] https://dlang.org/phobos/std_exception.html#assumeWontThrow

--


[Issue 17226] Exception during the generation of an assert message hides AssertError

2022-11-20 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17226

--- Comment #10 from Ali Cehreli  ---
(In reply to Paul Backus from comment #7)

> if the message expression throws, the assert's condition is never
> evaluated, and the program does not enter an invalid state.

Wait a minute... :) It shouldn't be the assert expression itself that puts the
program into invalid state. assert throws because the program is already in an
invalid state. Removing the evaluation of the assert expression does not change
that fact.

If we accept that point, then even attempting to evaluate the assert expression
is best-effort when the program is in an invalid state.

That and my earlier observation about attempting to dump call stack proves we
are already in a best-effort business when the program is in invalid state.

--


[Issue 17226] Exception during the generation of an assert message hides AssertError

2022-11-19 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17226

--- Comment #9 from Ali Cehreli  ---
I think the "invalid state" ship has sailed here because a D program by default
dumps backtrace to stderr. Can that always work? No, but I think we accept it
as best-effort.

I think the same applies to the assert message: A best-effort to show something
meaningful. May work but it should not hide the actual issue.

--


[Issue 17226] Exception during the generation of an assert message hides AssertError

2022-11-19 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17226

kinke  changed:

   What|Removed |Added

 CC||ki...@gmx.net

--- Comment #8 from kinke  ---
(In reply to Paul Backus from comment #7)
> Perhaps the simplest way to fix this is to have assert(condition, message)
> evaluate the message *first*

No. Changing the evaluation order would have a deep impact:

* Side effects of evaluating the msg first might change the assert condition's
outcome.
* You don't want a potentially expensive msg expression to be evaluated
unconditionally, i.e., including the regular case where the assertion holds.
* The msg expression may depend on the state after a failed condition - e.g.,
`assert(x.trySomething(), x.getLastErrorMsg())` (horrible, I know...).

--


[Issue 17226] Exception during the generation of an assert message hides AssertError

2022-11-19 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17226

Paul Backus  changed:

   What|Removed |Added

 CC||snarwin+bugzi...@gmail.com

--- Comment #7 from Paul Backus  ---
To be specific, the issue here is that according to the language spec:

> The first AssignExpression must evaluate to true. If it does not, an
> Assert Failure has occurred and the program enters an Invalid State.
>
> [...]
>
> Undefined Behavior: Once in an Invalid State the behavior of the
> continuing execution of the program is undefined.

i.e., once the condition has been evaluated to false, continuing to execute is
undefined *regardless* of what happens in the evaluation of the message.

Perhaps the simplest way to fix this is to have assert(condition, message)
evaluate the message *first*, so that Ali's example has behavior equivalent to
the following code:

---
import std.format;

void foo(int i) {
auto __msg = format("Bad parameter:", i);
assert(i == 42, __msg);
}

void main() {
foo(43);
}
---

This way, if the message expression throws, the assert's condition is never
evaluated, and the program does not enter an invalid state.

--


[Issue 17226] Exception during the generation of an assert message hides AssertError

2022-11-18 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17226

hst...@qfbox.info changed:

   What|Removed |Added

 CC||hst...@qfbox.info

--- Comment #6 from hst...@qfbox.info ---
Just use compile-time format string checking:

      assert(myAssumption, format!"%s doesn't work!"(blah));

This produces a compile error:

      string s = format!"blah %d blah"(123.45);

Problem solved.

--


[Issue 17226] Exception during the generation of an assert message hides AssertError

2022-11-18 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17226

--- Comment #5 from RazvanN  ---
Associated discussion about this:
https://forum.dlang.org/thread/qwixdanceeupdefyq...@forum.dlang.org

--


[Issue 17226] Exception during the generation of an assert message hides AssertError

2020-01-20 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17226

Heromyth  changed:

   What|Removed |Added

 CC||bitwo...@qq.com

--- Comment #4 from Heromyth  ---
We also encountered this problem. We can't find out which statement is wrong,
just get an error message.

--


[Issue 17226] Exception during the generation of an assert message hides AssertError

2017-03-10 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17226

RazvanN  changed:

   What|Removed |Added

 CC||razvan.nitu1...@gmail.com

--- Comment #3 from RazvanN  ---
Not sure if this is a dmd error. I think this might be druntime related :-?

--


[Issue 17226] Exception during the generation of an assert message hides AssertError

2017-02-26 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17226

j...@red.email.ne.jp changed:

   What|Removed |Added

   Keywords||EH
 CC||j...@red.email.ne.jp

--- Comment #2 from j...@red.email.ne.jp ---
Ah, I'd just been wondering why an assert message eats its location
information.
Come on, come on :)

--


[Issue 17226] Exception during the generation of an assert message hides AssertError

2017-02-26 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17226

Jack Stouffer  changed:

   What|Removed |Added

   Hardware|x86_64  |All
 OS|Linux   |All

--


[Issue 17226] Exception during the generation of an assert message hides AssertError

2017-02-26 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17226

Jack Stouffer  changed:

   What|Removed |Added

 CC||j...@jackstouffer.com

--- Comment #1 from Jack Stouffer  ---
Full example of catching the exception and still going

import std.string;
import std.stdio;

void foo(int i) {
// In this case a %s is forgotten but it could be any other trivial error.
assert(i == 42, format("Bad parameter:", i));
}

void main() {
try {
foo(43);
} catch (Exception) {
writeln("something threw");
}

writeln("This still runs despite being in undefined state");
}

Yeah, this is really, really bad.

--