Immich bindings and CLI in OCaml
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix immich exit

+37 -11
+1 -1
bin/cmd_server.ml
··· 38 38 | None -> 39 39 Fmt.epr "%a No server specified and not logged in.@." error_style "Error:"; 40 40 Fmt.epr "Use --server or login first.@."; 41 - exit 1 41 + raise (Immich_auth.Error.Exit_code 1) 42 42 in 43 43 (* Create session using requests config *) 44 44 let session = Requests.Cmd.create requests_config env sw in
+6
bin/main.ml
··· 31 31 in 32 32 Cmd.eval (Cmd.group info cmds) 33 33 with 34 + | Eio.Cancel.Cancelled Stdlib.Exit -> 35 + (* Eio wraps Exit in Cancelled when a fiber is cancelled *) 36 + 0 37 + | Immich_auth.Error.Exit_code code -> 38 + (* Exit code from Error.wrap - already printed error message *) 39 + code 34 40 | Openapi.Runtime.Api_error _ as exn -> 35 41 (* Handle Immich API errors with nice formatting *) 36 42 Immich_auth.Error.handle_exn exn
+5 -4
lib/cmd.ml
··· 88 88 error_style "Error:" 89 89 profile_style profile_name 90 90 Fmt.(styled `Bold string) "immich auth login"; 91 - exit 1 91 + raise (Error.Exit_code 1) 92 92 | Some session -> f fs session 93 93 94 94 let with_client ?requests_config ?profile f env = ··· 161 161 | Some _, Some _ -> 162 162 Fmt.epr "%a Cannot specify both --api-key and --email. Choose one authentication method.@." 163 163 error_style "Error:"; 164 - exit 1 164 + raise (Error.Exit_code 1) 165 165 166 166 let login_cmd env fs = 167 167 let doc = "Login to an Immich server." in 168 168 let info = Cmd.info "login" ~doc in 169 169 let login' (style_renderer, level) requests_config server api_key email password profile key_name = 170 170 setup_logging_with_config style_renderer level requests_config; 171 - login_action ~requests_config ~server ~api_key ~email ~password ~profile ~key_name env 171 + Error.wrap (fun () -> 172 + login_action ~requests_config ~server ~api_key ~email ~password ~profile ~key_name env) 172 173 in 173 174 Cmd.v info 174 175 Term.(const login' $ setup_logging $ requests_config_term fs $ server_arg $ api_key_arg $ email_arg $ password_arg $ profile_arg $ key_name_arg) ··· 302 303 Fmt.epr "%a %a@." 303 304 label_style "Available profiles:" 304 305 Fmt.(list ~sep:(any ", ") profile_style) profiles; 305 - exit 1 306 + raise (Error.Exit_code 1) 306 307 end 307 308 308 309 let profile_switch_cmd env =
+16 -4
lib/error.ml
··· 117 117 try f (); 0 118 118 with exn -> handle_exn exn 119 119 120 + (** Exception to signal desired exit code without calling [exit] directly. 121 + This avoids issues when running inside Eio's event loop. *) 122 + exception Exit_code of int 123 + 120 124 (** Wrap a command action to handle API errors gracefully. 121 125 122 126 This is designed to be used in cmdliner command definitions: ··· 133 137 ]} 134 138 135 139 The wrapper catches API errors and prints a nice message, 136 - then exits with an appropriate code. *) 140 + then raises [Exit_code] with an appropriate code. This exception 141 + should be caught by the main program outside the Eio event loop. *) 137 142 let wrap f = 138 143 try f () 139 - with exn -> 140 - let code = handle_exn exn in 141 - exit code 144 + with 145 + | Stdlib.Exit -> 146 + (* exit() was called somewhere - treat as success *) 147 + () 148 + | Eio.Cancel.Cancelled Stdlib.Exit -> 149 + (* Eio wraps Exit in Cancelled - treat as success *) 150 + () 151 + | exn -> 152 + let code = handle_exn exn in 153 + raise (Exit_code code)
+9 -2
lib/error.mli
··· 53 53 54 54 (** {1 Exception Handling} *) 55 55 56 + exception Exit_code of int 57 + (** Exception raised to signal a desired exit code. 58 + This is used instead of calling [exit] directly to avoid issues 59 + when running inside Eio's event loop. Catch this exception in 60 + the main program outside the Eio context. *) 61 + 56 62 val handle_exn : exn -> int 57 63 (** Handle an exception, printing a nice error message if it's an API error. 58 64 ··· 82 88 (** Wrap a command action to handle API errors gracefully. 83 89 84 90 This is designed to be used in cmdliner command definitions. 85 - Catches API errors, prints a nice message, and exits with 86 - an appropriate code. 91 + Catches API errors, prints a nice message, and raises {!Exit_code} 92 + with an appropriate code. The calling code should catch this 93 + exception outside the Eio event loop. 87 94 88 95 Usage: 89 96 {[