My aggregated monorepo of OCaml code, automaintained
0
fork

Configure Feed

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

Squashed 'ocaml-immich/' changes from bdf1942a..3e2de35f

3e2de35f Replace hand-written PeerTube library with OpenAPI-generated code
44465713 fix immich exit

git-subtree-dir: ocaml-immich
git-subtree-split: 3e2de35fec68787bf5ea7404b4b1d73d1faf787b

+61 -23
+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
+12 -6
immich.ml
··· 1333 1333 1334 1334 (** Get time buckets 1335 1335 1336 - Retrieve a list of all minimal time buckets. @param album_id Filter assets belonging to a specific album 1336 + Retrieve a list of all minimal time buckets. 1337 + @param album_id Filter assets belonging to a specific album 1337 1338 @param is_favorite Filter by favorite status (true for favorites only, false for non-favorites only) 1338 1339 @param is_trashed Filter by trash status (true for trashed assets only, false for non-trashed only) 1339 1340 @param order Sort order for assets within time buckets (ASC for oldest first, DESC for newest first) ··· 8182 8183 8183 8184 (** Retrieve memories statistics 8184 8185 8185 - Retrieve statistics about memories, such as total count and other relevant metrics. @param size Number of memories to return 8186 + Retrieve statistics about memories, such as total count and other relevant metrics. 8187 + @param size Number of memories to return 8186 8188 *) 8187 8189 let memories_statistics ?for_ ?is_saved ?is_trashed ?order ?size ?type_ client () = 8188 8190 let op_name = "memories_statistics" in ··· 11428 11430 11429 11431 (** Get time bucket 11430 11432 11431 - Retrieve a string of all asset ids in a given time bucket. @param album_id Filter assets belonging to a specific album 11433 + Retrieve a string of all asset ids in a given time bucket. 11434 + @param album_id Filter assets belonging to a specific album 11432 11435 @param is_favorite Filter by favorite status (true for favorites only, false for non-favorites only) 11433 11436 @param is_trashed Filter by trash status (true for trashed assets only, false for non-trashed only) 11434 11437 @param order Sort order for assets within time buckets (ASC for oldest first, DESC for newest first) ··· 13129 13132 13130 13133 (** Retrieve memories 13131 13134 13132 - Retrieve a list of memories. Memories are sorted descending by creation date by default, although they can also be sorted in ascending order, or randomly. @param size Number of memories to return 13135 + Retrieve a list of memories. Memories are sorted descending by creation date by default, although they can also be sorted in ascending order, or randomly. 13136 + @param size Number of memories to return 13133 13137 *) 13134 13138 let search_memories ?for_ ?is_saved ?is_trashed ?order ?size ?type_ client () = 13135 13139 let op_name = "search_memories" in ··· 13832 13836 13833 13837 (** Get all people 13834 13838 13835 - Retrieve a list of all people. @param page Page number for pagination 13839 + Retrieve a list of all people. 13840 + @param page Page number for pagination 13836 13841 @param size Number of items per page 13837 13842 *) 13838 13843 let get_all_people ?closest_asset_id ?closest_person_id ?page ?size ?with_hidden client () = ··· 14870 14875 14871 14876 (** List all albums 14872 14877 14873 - Retrieve a list of albums available to the authenticated user. @param asset_id Only returns albums that contain the asset 14878 + Retrieve a list of albums available to the authenticated user. 14879 + @param asset_id Only returns albums that contain the asset 14874 14880 Ignores the shared parameter 14875 14881 undefined: get all albums 14876 14882 *)
+12 -6
immich.mli
··· 711 711 712 712 (** Get time buckets 713 713 714 - Retrieve a list of all minimal time buckets. @param album_id Filter assets belonging to a specific album 714 + Retrieve a list of all minimal time buckets. 715 + @param album_id Filter assets belonging to a specific album 715 716 @param is_favorite Filter by favorite status (true for favorites only, false for non-favorites only) 716 717 @param is_trashed Filter by trash status (true for trashed assets only, false for non-trashed only) 717 718 @param order Sort order for assets within time buckets (ASC for oldest first, DESC for newest first) ··· 4400 4401 4401 4402 (** Retrieve memories statistics 4402 4403 4403 - Retrieve statistics about memories, such as total count and other relevant metrics. @param size Number of memories to return 4404 + Retrieve statistics about memories, such as total count and other relevant metrics. 4405 + @param size Number of memories to return 4404 4406 *) 4405 4407 val memories_statistics : ?for_:string -> ?is_saved:string -> ?is_trashed:string -> ?order:string -> ?size:string -> ?type_:string -> t -> unit -> ResponseDto.t 4406 4408 end ··· 6047 6049 6048 6050 (** Get time bucket 6049 6051 6050 - Retrieve a string of all asset ids in a given time bucket. @param album_id Filter assets belonging to a specific album 6052 + Retrieve a string of all asset ids in a given time bucket. 6053 + @param album_id Filter assets belonging to a specific album 6051 6054 @param is_favorite Filter by favorite status (true for favorites only, false for non-favorites only) 6052 6055 @param is_trashed Filter by trash status (true for trashed assets only, false for non-trashed only) 6053 6056 @param order Sort order for assets within time buckets (ASC for oldest first, DESC for newest first) ··· 6917 6920 6918 6921 (** Retrieve memories 6919 6922 6920 - Retrieve a list of memories. Memories are sorted descending by creation date by default, although they can also be sorted in ascending order, or randomly. @param size Number of memories to return 6923 + Retrieve a list of memories. Memories are sorted descending by creation date by default, although they can also be sorted in ascending order, or randomly. 6924 + @param size Number of memories to return 6921 6925 *) 6922 6926 val search_memories : ?for_:string -> ?is_saved:string -> ?is_trashed:string -> ?order:string -> ?size:string -> ?type_:string -> t -> unit -> ResponseDto.t 6923 6927 ··· 7251 7255 7252 7256 (** Get all people 7253 7257 7254 - Retrieve a list of all people. @param page Page number for pagination 7258 + Retrieve a list of all people. 7259 + @param page Page number for pagination 7255 7260 @param size Number of items per page 7256 7261 *) 7257 7262 val get_all_people : ?closest_asset_id:string -> ?closest_person_id:string -> ?page:string -> ?size:string -> ?with_hidden:string -> t -> unit -> ResponseDto.t ··· 7752 7757 7753 7758 (** List all albums 7754 7759 7755 - Retrieve a list of albums available to the authenticated user. @param asset_id Only returns albums that contain the asset 7760 + Retrieve a list of albums available to the authenticated user. 7761 + @param asset_id Only returns albums that contain the asset 7756 7762 Ignores the shared parameter 7757 7763 undefined: get all albums 7758 7764 *)
+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 {[