20.02.2024, 08.03.2024
The modern approach to exception handling in programming languages is terrible.
The current programming paradigm dictates that the code must be perfect, otherwise it will break the program. That is, if an exception occurs and the program is unable to cope with it, then it terminates its operation.
In other words, the program has no room for error. Not from the programmer, but from the program, since the error could have been caused by incorrectly specified parameters. It is clear that the blame for this can be shifted to the programmer and tester, who did not do additional data validation and exception handling, but there are many “buts”.
The main objection is that it is impossible to handle all exceptions at each stage. The current scheme of exceptions in development has led to the fact that developers, fearing that the program will crash and return run-time messages from the bytecode executor, figuratively speaking, put a condom on the program: at the beginning of the procedure there is a Try construct, at the end – a Catch for catching any exceptions in the middle of methods (procedures).
Secondly, not every exception is an error. An error when sending data, when a primary key is violated or when a foreign key is missing in a table, or even when writing data to disk is an unpleasant fact, but does not mean that the program cannot continue to be executed. Perhaps this will lead to logical errors in the future, but “show must go on”, in general the program must continue to be executed. If the user sees a logical error, he will react to it.
That is, even if memory addressing is violated, the program should not “die”, but should return an empty value (null). The exception must be recorded for deferred analysis of the problem that has arisen. And the user must be warned that “something went wrong” even in the most general terms. For him, this message should mean that the program’s actions can lead to logical errors.
At the same time, despite all the expressiveness in the reaction of the system (bytecode executor, translator, operating system) to exceptions, the number of exceptions themselves is not enough. In selective and continuous operations, in addition to the checks explicitly described by the programmer, incoming and outgoing checks must be performed to ensure that the data corresponds to its logical type. Not just that the value is a whole, but on the interpretation or meaning of this value. For example, a person’s age should not just be an integer value, but a number from 0 to 150.
In relational databases, the term “domain” was coined for this, although this did not contribute to the development of good data validation practices in them, and the introduction of Constrants (constraints) was more likely to cause additional unnecessary exceptions to arise in programs.
So, the occurrence of problems at the data validation level should rather generate a message of concern or warnings to the user about data revision, rather than an exception for the program, threatening its early and sudden death (General fault).
In other words, checks that throw exceptions must be done through non-linguistic means. The abundance of if…/case… significantly complicates and overloads the program with constructions that do not give the program expressiveness, and, on the contrary, are often intrusive and self-evident.
Violations of these rules should also not be handled or resolved in language ways – through explicit programming. An analogy is checking the correctness of data entry on a form, when validation occurs after entry, and in the case of empty fields or if the logic for filling in the fields is violated, the program asks the user to fill them out correctly.
Another example of non-linguistic methods is implicit type conversion, the use of generic types such as var/variable, dynamic, generic class types (object), and duck typing.
Similarly, when processing values in bulk, some data may not be processed, for example, due to insufficient or inconsistent data. And then the system can ask the user to correct only this data, and then process it in the second iteration.
The idea of external exception management resonates with different levels of human thinking. The subconscious acts according to the laid down program, mechanically working it out. Some checks may be embedded in the subconscious. At the lower level of the subconscious, the brain checks the operation of the program at key points, and in the event of an exception, consciousness comes into play, figuring out what went wrong, why, and what needs to be done to bring the program back to normal.