# Partial match: Style advice

**URL:** <https://discuss.ocaml.org/t/partial-match-style-advice/17869>\
**Category:** Learning\
**Tags:** style\
**Created:** [March 4, 2026, 5:59pm UTC](https://discuss.ocaml.org/t/partial-match-style-advice/17869 "2026-03-04T17:59:51Z")\
**Posts on this page:** 1\
**Showing post:** 16

<div class="post-metadata">

**Author:** ![octachron](https://avatars.discourse-cdn.com/v4/letter/o/49beb7/32.png) [@octachron](https://discuss.ocaml.org/u/octachron)\
**Post date:** [March 5, 2026, 11:12pm UTC](https://discuss.ocaml.org/t/partial-match-style-advice/17869/16 "2026-03-05T23:12:46Z")

</div>

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

```ocaml
try x.(n) with Invalid_argument _ -> ...

```

but

```ocaml
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

```ocaml
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

```ocaml
let f x = match remove_A x with
| A ->
   (* `remove_A makes this case impossible *)
   assert false
| B -> ()

```

```auto
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.

---

_[View the full topic](https://discuss.ocaml.org/t/partial-match-style-advice/17869)._
