October 22, 2020
On Thursday, 22 October 2020 at 20:23:49 UTC, Ali Çehreli wrote:
> On 10/21/20 9:04 PM, Mathias LANG wrote:
>
> > *do not catch Error*. Catching
> > `Error` is a sin, a crime, and every catch of `Error`
> derivative should
> > have you outraged. It is in direct violation of the specs. And
> > obviously, it's also incompatible with scheme that do not
> throw an `Error`.
>
> That's true but I will recommend catching Error in both of my upcoming DConf Online presentations. :)
>
> 1) Thread entry functions should catch and report any Throwable. Otherwise, main thread will see only a timeout and stack trace of the worker will lost.

Once an Error has been thrown, the program is in an invalid state, and anything you do *on any thread* has undefined behavior. The only thing you can do safely is terminate the entire process. Stack traces can be retrieved after the fact from a core dump.

October 22, 2020
On Thursday, 22 October 2020 at 20:23:49 UTC, Ali Çehreli wrote:
> 1) Thread entry functions should catch and report any Throwable. Otherwise, main thread will see only a timeout and stack trace of the worker will lost.

Worth remembering catching actually loses valuable information when running in a debugger and/or with core dumps enabled.

If you did want to do this, at a minimum it would have to honor the DRT-trapExceptions value.
October 22, 2020
On 10/22/20 1:33 PM, Paul Backus wrote:

> Once an Error has been thrown, the program is in an invalid state, and
> anything you do *on any thread* has undefined behavior. The only thing
> you can do safely is terminate the entire process. Stack traces can be
> retrieved after the fact from a core dump.

Which means:

1) Must still catch Error in a worker thread to be able to abort the whole program. Otherwise no other thread is aware.

2) Is the default behavior of D runtime dumping stack trace correct? On the one hand, it attempts to do something, which should not be attempted. On the other hand, it does report after the program code has stopped: there is only the stderr stream at that point.

Makes sense?

Thank you,
Ali

October 22, 2020
On Thu, Oct 22, 2020 at 07:31:39PM +0000, Kagamin via Digitalmars-d wrote:
> On Thursday, 22 October 2020 at 16:30:57 UTC, H. S. Teoh wrote:
> > The problem with that is that it quickly falls into the paradox of who watches the watchers.  The next thing you know, I'm asking for a way to test that my code that catches asserts are actually catching asserts.  Next year I'll be asking for code to test my code that tests code that catches asserts. It never ends.
> 
> Paradoxes don't exist. Tests are watchers, and practice shows their presence is better than their absence.

I agree tests are watchers.  But it starts a bit ridiculous when you need to test your tests...


T

-- 
Prosperity breeds contempt, and poverty breeds consent. -- Suck.com
October 22, 2020
On 10/22/20 1:38 PM, Adam D. Ruppe wrote:

> If you did want to do this, at a minimum it would have to honor the DRT-trapExceptions value.

Great advice! Created a documentation issue for this nonexistent feature. :)

  https://issues.dlang.org/show_bug.cgi?id=21339

Ali
October 22, 2020
On Thu, Oct 22, 2020 at 03:18:03PM -0400, Steven Schveighoffer via Digitalmars-d wrote: [...]
> Another thing I've advocated for strongly is to not run imported unittests ever, even in templates.
[...]

+1.  This has necessitated the silly StdUnittest hack in Phobos, and AFAIK no other D library has used a similar hack, which means that every single time somebody imports an 3rd party library and compiles with -unittest, the library's unittests get run all over again for the millionth time.  It's useless weight and redundant work, and should be eliminated.


T

-- 
Democracy: The triumph of popularity over principle. -- C.Bond
October 23, 2020
On 22.10.20 18:28, Timon Gehr wrote:
> 
> Also, code that "relies on such unwinding" can be annotated @safe and the compiler won't complain.

Actually, it will complain. Sorry for the noise, should have double-checked before sending the post.

However, in contracts do rely on catching AssertError, and they are allowed in @safe code:

---
void bar()@safe{
    import std.stdio;
    writeln("throwing an AssertError");
    assert(0);
}
void main()@safe{
    class C{
        void foo()@safe in{ bar(); }do{}
    }
    class D:C{
        override void foo()@safe in{}do{}
    }
    auto d=new D;
    d.foo();
}
---

Prints:
throwing an AssertError

The program does not abort.

If catching an AssertError is UB, why does the language do it in @safe code?
October 23, 2020
On Thursday, 22 October 2020 at 20:58:50 UTC, Ali Çehreli wrote:
> On 10/22/20 1:38 PM, Adam D. Ruppe wrote:
>
>> If you did want to do this, at a minimum it would have to honor the DRT-trapExceptions value.
>
> Great advice! Created a documentation issue for this nonexistent feature. :)
>
>   https://issues.dlang.org/show_bug.cgi?id=21339
>
> Ali

I definitely need to read 'This week in D' more constantly!

:-P
October 23, 2020
On Thursday, 22 October 2020 at 16:05:51 UTC, Mathias LANG wrote:

> You do not test for assert error. Assert errors are logic errors, and if they get triggered, all bets are off.
>
> You disagree with the spec then. The spec says that the stack might not be unwound if an `Error` is thrown.

It's not that simple, you need to read the whole spec ;). The spec for unit tests has an exception:

"Individual tests are specified in the unit test using AssertExpressions. Unlike AssertExpressions used elsewhere, the assert is not assumed to hold, and upon assert failure the program is still in a defined state." [1].

Although, it's not clear if that only applies to `assert` directly in the `unittest` block or any assert reachable through the `unittest` block.

Regardless of what's correct or not, I think there must be a way to have unit tests keep running after a failed test. Otherwise D will have very poor experience for unit test frameworks. It's already bad enough with the default unit test runner that aborts the rest of the unit tests inside a module after a failed test (it will continue with other modules).

[1] https://dlang.org/spec/unittest.html

--
/Jacob Carlborg

October 23, 2020
On Thursday, 22 October 2020 at 16:18:14 UTC, H. S. Teoh wrote:

> 	template MyTemplate(T)
> 	{
> 		auto myFunc(...) { ... }
>
> 		/// This is instantiated once per template instantiation
> 		unittest {
> 			pragma(msg, T.stringof);
> 		}
>
> 		/// This is instantiated only once, ever
> 		/// (The use of 'static' is hypothetical syntax, it can
> 		/// be anything else that marks the unittest as
> 		/// single-instance)
> 		static unittest {
> 			//pragma(msg, T.stringof); // Error: cannot reference T here
>
> 			// Have to explicitly instantiate the template
> 			// with the arguments you want to test for
> 			alias U = MyTemplate!int;
> 		}
> 	}

Might be a bit confusing when the unit test is inside a templated class. Because the unit test function is already static, relative to the class.

--
/Jacob Carlborg