An Assert_failure _ means that an unreachable code path has been reached, thus the state of your program is compromised. Catching specifically this exception reflects a contradiction in your mind map of your code base: if you write an exception handler for Assert_failure _ because you believe that the assertion may be false sometimes, you should use another error handling mechanism. (It still might makes sense to log the assertion failure properly in an user-facing service.)
The Invalid_argument exception means that the user of a function failed to satisfy some easily-checkable preconditions of the function. Rather than catching the exception, you should check the preconditions. In other words, you shouldn’t write
try x.(n) with Invalid_argument _ -> ...
but
if n < 0 || n >= Array.length x then ...
Finally, many people consider than the non-exhautiveness pattern warning is better promoted to a compiler error (with -w @8). Moreover, the issue with disabling the warning locally is that you can no longer narrows the case that are impossible. Compare for instance
type t = A | B | C
let remove_A = function A -> B | x -> x
let f x = match[@warning "-partial-match"] remove_A x with
| B -> ()
(* someone added the constructor C after that the function was written,
and no one saw that the `C` case was missing *)
with
let f x = match remove_A x with
| A ->
(* `remove_A makes this case impossible *)
assert false
| B -> ()
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched: C
In the second case, the assertion is both narrow and the assert false branch is a good place to comment why the assertion is always true.
I mean: Why would a server process, for example, not catch when these are raised in a handler or worker if high-availability is demanded
If you can tear down part of the program and restores the state of the service in case of exceptions, you should catch all exceptions (but can you really recover from an Out_of_memory or Stack_overflow exception?) rather than single out “someone has made a programming error” exceptions.
The advice about not catching Assert_failure, Match_failure, Invalid_argument is that those exceptions denote programming errors that should be statically avoidable. And thus to preserve the status of those exceptions as panic exceptions, you should not trigger knowingly those exceptions while simultaneously correcting them at runtime with an exception handler.