On Aug 1, 1:57 am, bravegag <brave...@[EMAIL PROTECTED]
> wrote:
> Hi Colin,
>
> Many thanks for your feedback.
>
> On Jul 29, 10:08 am, Colin LeMahieu <clemah...@[EMAIL PROTECTED]
> wrote:>
Exceptions are used to handle cases where the failure result could not
> > have been predicted beforehand. A network communications failure
> > cannot be tested for and you can only observe its occurrence once it
> > has happened.
>
> You have somehow mentioned it in this paragraph which is my point
> about module boundaries.
>
> Suppose you develop a new Socket library API. You can and will test
> all invalid cases that you could foresee as invalid uses of your
> library. Optimally you would offer an extensive test-coverage and
> examples of use of the library. Still your library as a separate
> module DOES NOT know by whom and how it is going to be used in the
> future. It is a reusable class library API right? so future and
> unknown clients of this library:
>
> - Must not know the library guts to be able to use it, which is the
> case when they while using it start receiving any kind of assertion
> violations from deep in the library code. There should be a defensive
> layer around i.e. what Bertrand calls filter modules that ensure the
> input is valid in the first place. But the reaction to invalid input
> are Exceptions not assertions.
>
> - Have the ability to recover at runtime from violations of the filter
> modules otherwise unknown clients will not have any chance to recover
> from filter module invalid input violations.
>
> I personally would have a very bad feeling delivering such a reusable
> class library
> API (what I call module) to clients knowing they:
>
> - Will have to test and debug my library finding out assetion
> violations deep in my code rather that knowing upfront all invalid
> input situations via exception in the module boundaries "throws"
> declarations in Java.
>
> - Will not have any chance to recover from possible assertion
> (preconditions) violations which are not clearly stated in the
> publicly visible API interfaces.
>
> Many thanks for the interesting discussion.
>
> Best Regards,
> Giovanni
I think this stems from a misunderstanding of responsibility
assignment associated with preconditions and postconditions.
Precondition violations mean the caller has a bug. Postcondition
violations mean the calee has a bug. If you have completely tested
your public library, all internal calls would not have possibility of
tripping another internal assertion. Each feature with a contract
states "if you give me this 'require', I can give you this 'ensure'"
There will never be such a thing as a *deep assertion violation*
Every assertion violation should occur at the API boundries between
unknown -> library and it should only be a precondition violation
which would point the blame at the unknown. If there is an assertion
violation *deep* in a library call such as: unknown -> library ->
(library -> library) between two library calls, the blame is not on
the unknown, it's actually on your library. Your library passed
invalid input to another library call, you may say "well that's
because the unknown passed in bad input." But according to your
contracts that's not so. The violation didn't occur at: (unknown ->
library) -> library -> library, it occurred at: unknown -> library ->
(library -> library) meaning according to your library *definition*
the input from unknown to library was valid but your library crashed,
you have a bug, not them.


|