On Saturday, 4 June 2022 at 14:05:14 UTC, Paul Backus wrote:
[...]
What does that mean? Am I `Error` blind?
Generally you do not need to subclass `Error` yourself. The
most common way of throwing an `Error` in user code is to use
`assert`, which (with default compiler flags) throws an
`AssertError` on failure. Function contracts and struct/class
invariants work the same way.
`git grep -Enw 'assert|unittest'` reveals that my code contains
assert statements only in unittests. Someone (was it Walter?)
once pointed out that asserts are ignored in relase mode (like C
assert) and that for my purposes `enforce` (i.e. throw an
Exception) is best suited.
3. Can you provide some piece of code which *must* throw
`Error` and cannot
throw an appropriate Exception?
This is entirely a question of API design. If it should be the
caller's responsibility to check for some condition before
calling the function, then you can throw an `Error` when that
condition does not hold (or more likely, use an `assert` or an
`in` contract to check for it).
Provided one does not catch `Error`s this means one has to
isolate such an API design by using a subprocess. This is what
one usually tries to avoid.
If it should be the callee's responsibility to check, you
should throw an `Exception` (or use `enforce`).
If the library always throws exceptions it can be used in both
API "designs". In the case that the implementor of the caller
expects `Error`s instead of `Exceptions` she could use a small
wrapper which catches the Exceptions and rethrows them as
`Error`s. Likewise for error codes.
Using contracts and invariants impedes this approach.