1313 *)
1414module U = Unix
1515module R = Rpc
16+ module B = Backtrace
1617
1718open Core.Std
1819open Async.Std
1920
21+ open Types
22+
2023let use_syslog = ref false
2124
2225let info fmt =
2326 Printf. ksprintf (fun s ->
2427 if ! use_syslog then begin
2528 (* FIXME: this is synchronous and will block other I/O *)
26- Core.Syslog. syslog ~level: Core.Syslog.Level. INFO ~add_stderr: true s;
29+ Core.Syslog. syslog ~level: Core.Syslog.Level. INFO s;
2730 return ()
2831 end else begin
2932 let w = Lazy. force Writer. stderr in
@@ -38,6 +41,20 @@ let backend_error name args =
3841 let exnty = Exception. Backend_error (name, args) in
3942 Exception. rpc_of_exnty exnty
4043
44+ let backend_backtrace_error name args error =
45+ match List. zip error.files error.lines with
46+ | None -> backend_error " SCRIPT_FAILED" [ " malformed backtrace in error output" ]
47+ | Some pairs ->
48+ let backtrace =
49+ pairs
50+ |> List. map ~f: (fun (filename , line ) -> { B.Interop. filename; line })
51+ |> B.Interop. to_backtrace
52+ |> B. sexp_of_t
53+ |> Sexplib.Sexp. to_string in
54+ let open Storage_interface in
55+ let exnty = Exception. Backend_error_with_backtrace (name, backtrace :: args) in
56+ Exception. rpc_of_exnty exnty
57+
4158let missing_uri () =
4259 backend_error " MISSING_URI" [ " Please include a URI in the device-config" ]
4360
@@ -70,7 +87,16 @@ let fork_exec_rpc root_dir script_name args response_of_rpc =
7087 >> = fun output ->
7188 begin match output.Process.Output. exit_status with
7289 | Error (`Exit_non_zero code ) ->
73- return (Error (backend_error " SCRIPT_FAILED" [ script_name; " non-zero exit" ; string_of_int code; output.Process.Output. stdout; output.Process.Output. stderr ]))
90+ (* Expect an exception and backtrace on stderr *)
91+ begin match Or_error. try_with (fun () -> Jsonrpc. of_string output.Process.Output. stderr) with
92+ | Error _ ->
93+ return (Error (backend_error " SCRIPT_FAILED" [ script_name; " non-zero exit and bad json on stderr" ; string_of_int code; output.Process.Output. stdout; output.Process.Output. stderr ]))
94+ | Ok response ->
95+ begin match Or_error. try_with (fun () -> error_of_rpc response) with
96+ | Error _ -> return (Error (backend_error " SCRIPT_FAILED" [ script_name; " non-zero exit and bad json on stderr" ; string_of_int code; output.Process.Output. stdout; output.Process.Output. stderr ]))
97+ | Ok x -> return (Error (backend_backtrace_error " SCRIPT_FAILED" [ script_name; " non-zero exit" ; string_of_int code; output.Process.Output. stdout ] x))
98+ end
99+ end
74100 | Error (`Signal signal ) ->
75101 return (Error (backend_error " SCRIPT_FAILED" [ script_name; " signalled" ; Signal. to_string signal; output.Process.Output. stdout; output.Process.Output. stderr ]))
76102 | Ok () ->
0 commit comments