Specific reason for not embracing the use of exceptions for error propagation?

I’m on board with giving the programmer a hint that a function might fail, but how do you avoid contaminating the type of other functions? An immediate failwith?

In the following code, f1 and f2 return an Or_error.t even though their caller can do nothing to prevent it. Now our codebase has 3 functions whose return types tell the programmer to be careful but there’s nothing to be careful about when calling the last two.

let divide a b =
  if b = 0 then
    Error (Error.of_string "Division by zero")
  else
    Ok (a / b)

let f1 () =
  divide 0 0

let f2 () =
  f1 ()

So, the way I’d write my code is:

let divide a b =
  if b = 0 then
    Error (Error.of_string "Division by zero")
  else
    Ok (a / b)

let f1 () =
  match divide 0 0 with
  | Ok x -> x
  | Error e -> Error.raise e

let f2 () =
  f1 ()

Now both f1 and f2 return a plain int and the programmer’s attention is drawn to divide. Is this recommended usage, as opposed to monadic propagation?