Merge Typing_logic.Coerce and Typing_logic.IsSubtype
[hiphop-php.git] / hphp / hack / src / dfind / dfindMaybe.ml
blob61c047298e827c1b596c3f661e80e448c1d87d8d
1 (*
2 * Copyright (c) 2015, Facebook, Inc.
3 * All rights reserved.
5 * This source code is licensed under the MIT license found in the
6 * LICENSE file in the "hack" directory of this source tree.
8 *)
10 (*****************************************************************************)
11 (* A modified maybe monad
12 * Most of the time, I prefer to use exceptions, I like things to blow up
13 * if something went wrong.
14 * However, in the case of dfind, exceptions are painful. We don't want things
15 * to blow-up, we want to carry-on whatever happens.
16 * So this monad never fails, it logs very nasty errors, for example, it will
17 * log the fact that a watch couldn't be created, when the file still exists.
19 (*****************************************************************************)
21 let log = ref stderr
23 let set_log oc = log := oc
25 type 'a t = 'a option
27 let ( >>= ) x f =
28 match x with
29 | None -> None
30 | Some x -> f x
32 let return x = Some x
34 let handle_file_exn path = function
35 | Fsnotify.Error (_, Unix.ENOENT) ->
36 () (* The file got deleted in the mean time ... we don't care *)
37 | Fsnotify.Error (reason, _) ->
38 (* This is bad ... *)
39 Printf.fprintf !log "Error: could not add watch to %s [%s]\n" path reason
40 | _ when Sys.file_exists path ->
41 (* Logging this makes the system very noisy. There are too many
42 * cases where a file has been removed etc ...
45 | _ -> ()
47 (* Calls (f path), never fails, logs the nasty exceptions *)
48 let call f path =
49 try f path with
50 | e ->
51 handle_file_exn path e;
52 None
54 let wrap f x = return (f x)