From 94fab24f031a22281992da12a2a87174999ae562 Mon Sep 17 00:00:00 2001 From: Marshall Roch Date: Fri, 13 Dec 2019 08:36:43 -0500 Subject: [PATCH] Sync hack changes --- hack/utils/core/exception.ml | 6 +++++- hack/utils/core/exception.mli | 2 ++ hack/utils/core/hh_logger.ml | 3 +++ hack/utils/core/hh_logger.mli | 2 ++ hack/watchman/watchman.ml | 29 ++++++++++++----------------- hack/watchman/watchman_lwt.ml | 11 +++++------ hack/watchman/watchman_sig.ml | 4 +--- 7 files changed, 30 insertions(+), 27 deletions(-) diff --git a/hack/utils/core/exception.ml b/hack/utils/core/exception.ml index 79ec2433bbe..31d7d59adca 100644 --- a/hack/utils/core/exception.ml +++ b/hack/utils/core/exception.ml @@ -30,11 +30,15 @@ let wrap exn = (* The inverse of `wrap`, returns the wrapped `exn`. You might use this to pattern match on the raw exception or print it, but should not reraise it since it - will not include the correct backtrace; use `reraise` instead. *) + will not include the correct backtrace; use `reraise` or `to_exn` instead. *) let unwrap { exn; backtrace = _ } = exn let reraise { exn; backtrace } = Printexc.raise_with_backtrace exn backtrace +(* Converts back to an `exn` with the right backtrace. Generally, avoid this in favor of + the helpers in this module, like `to_string` and `get_backtrace_string`. *) +let to_exn t = (try reraise t with exn -> exn) + (* Like `wrap`, but for the unusual case where you want to create an `Exception` for an un-raised `exn`, capturing its stack trace. If you've caught an exception, you should use `wrap` instead, since it already has a stack trace. *) diff --git a/hack/utils/core/exception.mli b/hack/utils/core/exception.mli index ab56ef2532b..90632c6157d 100644 --- a/hack/utils/core/exception.mli +++ b/hack/utils/core/exception.mli @@ -15,6 +15,8 @@ val unwrap : t -> exn val reraise : t -> 'a +val to_exn : t -> exn + val to_string : t -> string val get_ctor_string : t -> string diff --git a/hack/utils/core/hh_logger.ml b/hack/utils/core/hh_logger.ml index 821a3495399..f984b9991e2 100644 --- a/hack/utils/core/hh_logger.ml +++ b/hack/utils/core/hh_logger.ml @@ -80,6 +80,9 @@ let print_duration name t = let exc ?(prefix : string = "") ~(stack : string) (e : exn) : unit = print_with_newline "%s%s\n%s" prefix (Printexc.to_string e) stack +let exception_ ?(prefix : string = "") (e : Exception.t) : unit = + exc ~prefix ~stack:(Exception.get_backtrace_string e) (Exception.unwrap e) + module Level : sig type t = | Off diff --git a/hack/utils/core/hh_logger.mli b/hack/utils/core/hh_logger.mli index 4893a1c3873..a958c8ab790 100644 --- a/hack/utils/core/hh_logger.mli +++ b/hack/utils/core/hh_logger.mli @@ -24,6 +24,8 @@ val print_duration : string -> float -> float val exc : ?prefix:string -> stack:string -> exn -> unit +val exception_ : ?prefix:string -> Exception.t -> unit + module Level : sig type t = | Off diff --git a/hack/watchman/watchman.ml b/hack/watchman/watchman.ml index d1e99007e33..380d0d4ba4d 100644 --- a/hack/watchman/watchman.ml +++ b/hack/watchman/watchman.ml @@ -107,11 +107,7 @@ end = struct let return x = x - let catch ~f ~catch = - try f () - with exn -> - let stack = Printexc.get_backtrace () in - catch ~stack exn + let catch ~f ~catch = (try f () with exn -> catch (Exception.wrap exn)) let list_fold_values = List.fold @@ -481,16 +477,15 @@ module Functor (Watchman_process : Watchman_sig.WATCHMAN_PROCESS) : (****************************************************************************) let with_crash_record_exn source f = - Watchman_process.catch ~f ~catch:(fun ~stack e -> - Hh_logger.exc ~prefix:("Watchman " ^ source ^ ": ") ~stack e; - raise e) + Watchman_process.catch ~f ~catch:(fun exn -> + Hh_logger.exception_ ~prefix:("Watchman " ^ source ^ ": ") exn; + Exception.reraise exn) let with_crash_record_opt source f = Watchman_process.catch ~f:(fun () -> with_crash_record_exn source f >|= fun v -> Some v) - ~catch:(fun ~stack:_ e -> - let exn = Exception.wrap e in - match e with + ~catch:(fun exn -> + match Exception.unwrap exn with (* Avoid swallowing these *) | Exit_status.Exit_with _ | Watchman_restarted -> @@ -610,7 +605,7 @@ module Functor (Watchman_process : Watchman_sig.WATCHMAN_PROCESS) : ~conn (watch_project (Path.to_string path)) >|= fun response -> Some response) - ~catch:(fun ~stack:_ _ -> Watchman_process.return None) + ~catch:(fun _ -> Watchman_process.return None) >|= fun response -> match response with | None -> @@ -791,8 +786,8 @@ module Functor (Watchman_process : Watchman_sig.WATCHMAN_PROCESS) : ~f:(fun () -> with_crash_record_exn source (fun () -> f env) >|= fun (env, result) -> (Watchman_alive env, result)) - ~catch:(fun ~stack exn -> - match exn with + ~catch:(fun exn -> + match Exception.unwrap exn with | Sys_error msg when msg = "Broken pipe" -> Hh_logger.log "Watchman Pipe broken."; close_channel_on_instance env @@ -825,8 +820,8 @@ module Functor (Watchman_process : Watchman_sig.WATCHMAN_PROCESS) : | Watchman_error msg -> Hh_logger.log "Watchman error: %s. Closing channel" msg; close_channel_on_instance env - | e -> - let msg = Printf.sprintf "%s\n%s" (Exn.to_string e) stack in + | _ -> + let msg = Exception.to_string exn in EventLogger.watchman_uncaught_failure msg; raise Exit_status.(Exit_with Watchman_failed)) in @@ -850,7 +845,7 @@ module Functor (Watchman_process : Watchman_sig.WATCHMAN_PROCESS) : >|= fun response -> env.clockspec <- J.get_string_val "clock" response; extract_file_names env response) - ~catch:(fun ~stack:_ _ -> raise Exit_status.(Exit_with Watchman_failed)) + ~catch:(fun _ -> raise Exit_status.(Exit_with Watchman_failed)) let make_state_change_response state name data = let metadata = J.try_get_val "metadata" data in diff --git a/hack/watchman/watchman_lwt.ml b/hack/watchman/watchman_lwt.ml index d8b667e08ca..4f7deecf60f 100644 --- a/hack/watchman/watchman_lwt.ml +++ b/hack/watchman/watchman_lwt.ml @@ -22,13 +22,12 @@ module Lwt_watchman_process : let return = Lwt.return - external reraise : exn -> 'a = "%reraise" - let catch ~f ~catch = - Lwt.catch f (fun e -> - match e with - | Lwt.Canceled -> reraise e - | e -> catch ~stack:(Printexc.get_backtrace ()) e) + Lwt.catch f (fun exn -> + let e = Exception.wrap exn in + match exn with + | Lwt.Canceled -> Exception.reraise e + | _ -> catch e) let list_fold_values l ~init ~f = Lwt_list.fold_left_s f init l diff --git a/hack/watchman/watchman_sig.ml b/hack/watchman/watchman_sig.ml index 350dd8147d8..9d3840c6fe4 100644 --- a/hack/watchman/watchman_sig.ml +++ b/hack/watchman/watchman_sig.ml @@ -105,9 +105,7 @@ module type WATCHMAN_PROCESS = sig val return : 'a -> 'a result val catch : - f:(unit -> 'b result) -> - catch:(stack:string -> exn -> 'b result) -> - 'b result + f:(unit -> 'b result) -> catch:(Exception.t -> 'b result) -> 'b result val list_fold_values : 'a list -> init:'b -> f:('b -> 'a -> 'b result) -> 'b result