···3838 | None ->
3939 Fmt.epr "%a No server specified and not logged in.@." error_style "Error:";
4040 Fmt.epr "Use --server or login first.@.";
4141- exit 1
4141+ raise (Immich_auth.Error.Exit_code 1)
4242 in
4343 (* Create session using requests config *)
4444 let session = Requests.Cmd.create requests_config env sw in
+6
bin/main.ml
···3131 in
3232 Cmd.eval (Cmd.group info cmds)
3333 with
3434+ | Eio.Cancel.Cancelled Stdlib.Exit ->
3535+ (* Eio wraps Exit in Cancelled when a fiber is cancelled *)
3636+ 0
3737+ | Immich_auth.Error.Exit_code code ->
3838+ (* Exit code from Error.wrap - already printed error message *)
3939+ code
3440 | Openapi.Runtime.Api_error _ as exn ->
3541 (* Handle Immich API errors with nice formatting *)
3642 Immich_auth.Error.handle_exn exn
+12-6
immich.ml
···1333133313341334 (** Get time buckets
1335133513361336- Retrieve a list of all minimal time buckets. @param album_id Filter assets belonging to a specific album
13361336+ Retrieve a list of all minimal time buckets.
13371337+ @param album_id Filter assets belonging to a specific album
13371338 @param is_favorite Filter by favorite status (true for favorites only, false for non-favorites only)
13381339 @param is_trashed Filter by trash status (true for trashed assets only, false for non-trashed only)
13391340 @param order Sort order for assets within time buckets (ASC for oldest first, DESC for newest first)
···8182818381838184 (** Retrieve memories statistics
8184818581858185- Retrieve statistics about memories, such as total count and other relevant metrics. @param size Number of memories to return
81868186+ Retrieve statistics about memories, such as total count and other relevant metrics.
81878187+ @param size Number of memories to return
81868188 *)
81878189 let memories_statistics ?for_ ?is_saved ?is_trashed ?order ?size ?type_ client () =
81888190 let op_name = "memories_statistics" in
···11428114301142911431 (** Get time bucket
11430114321143111431- Retrieve a string of all asset ids in a given time bucket. @param album_id Filter assets belonging to a specific album
1143311433+ Retrieve a string of all asset ids in a given time bucket.
1143411434+ @param album_id Filter assets belonging to a specific album
1143211435 @param is_favorite Filter by favorite status (true for favorites only, false for non-favorites only)
1143311436 @param is_trashed Filter by trash status (true for trashed assets only, false for non-trashed only)
1143411437 @param order Sort order for assets within time buckets (ASC for oldest first, DESC for newest first)
···13129131321313013133 (** Retrieve memories
13131131341313213132- 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
1313513135+ 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.
1313613136+ @param size Number of memories to return
1313313137 *)
1313413138 let search_memories ?for_ ?is_saved ?is_trashed ?order ?size ?type_ client () =
1313513139 let op_name = "search_memories" in
···13832138361383313837 (** Get all people
13834138381383513835- Retrieve a list of all people. @param page Page number for pagination
1383913839+ Retrieve a list of all people.
1384013840+ @param page Page number for pagination
1383613841 @param size Number of items per page
1383713842 *)
1383813843 let get_all_people ?closest_asset_id ?closest_person_id ?page ?size ?with_hidden client () =
···14870148751487114876 (** List all albums
14872148771487314873- Retrieve a list of albums available to the authenticated user. @param asset_id Only returns albums that contain the asset
1487814878+ Retrieve a list of albums available to the authenticated user.
1487914879+ @param asset_id Only returns albums that contain the asset
1487414880 Ignores the shared parameter
1487514881 undefined: get all albums
1487614882 *)
+12-6
immich.mli
···711711712712 (** Get time buckets
713713714714- Retrieve a list of all minimal time buckets. @param album_id Filter assets belonging to a specific album
714714+ Retrieve a list of all minimal time buckets.
715715+ @param album_id Filter assets belonging to a specific album
715716 @param is_favorite Filter by favorite status (true for favorites only, false for non-favorites only)
716717 @param is_trashed Filter by trash status (true for trashed assets only, false for non-trashed only)
717718 @param order Sort order for assets within time buckets (ASC for oldest first, DESC for newest first)
···4400440144014402 (** Retrieve memories statistics
4402440344034403- Retrieve statistics about memories, such as total count and other relevant metrics. @param size Number of memories to return
44044404+ Retrieve statistics about memories, such as total count and other relevant metrics.
44054405+ @param size Number of memories to return
44044406 *)
44054407 val memories_statistics : ?for_:string -> ?is_saved:string -> ?is_trashed:string -> ?order:string -> ?size:string -> ?type_:string -> t -> unit -> ResponseDto.t
44064408end
···6047604960486050 (** Get time bucket
6049605160506050- Retrieve a string of all asset ids in a given time bucket. @param album_id Filter assets belonging to a specific album
60526052+ Retrieve a string of all asset ids in a given time bucket.
60536053+ @param album_id Filter assets belonging to a specific album
60516054 @param is_favorite Filter by favorite status (true for favorites only, false for non-favorites only)
60526055 @param is_trashed Filter by trash status (true for trashed assets only, false for non-trashed only)
60536056 @param order Sort order for assets within time buckets (ASC for oldest first, DESC for newest first)
···6917692069186921 (** Retrieve memories
6919692269206920- 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
69236923+ 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.
69246924+ @param size Number of memories to return
69216925 *)
69226926 val search_memories : ?for_:string -> ?is_saved:string -> ?is_trashed:string -> ?order:string -> ?size:string -> ?type_:string -> t -> unit -> ResponseDto.t
69236927···7251725572527256 (** Get all people
7253725772547254- Retrieve a list of all people. @param page Page number for pagination
72587258+ Retrieve a list of all people.
72597259+ @param page Page number for pagination
72557260 @param size Number of items per page
72567261 *)
72577262 val get_all_people : ?closest_asset_id:string -> ?closest_person_id:string -> ?page:string -> ?size:string -> ?with_hidden:string -> t -> unit -> ResponseDto.t
···7752775777537758 (** List all albums
7754775977557755- Retrieve a list of albums available to the authenticated user. @param asset_id Only returns albums that contain the asset
77607760+ Retrieve a list of albums available to the authenticated user.
77617761+ @param asset_id Only returns albums that contain the asset
77567762 Ignores the shared parameter
77577763 undefined: get all albums
77587764 *)
+5-4
lib/cmd.ml
···8888 error_style "Error:"
8989 profile_style profile_name
9090 Fmt.(styled `Bold string) "immich auth login";
9191- exit 1
9191+ raise (Error.Exit_code 1)
9292 | Some session -> f fs session
93939494let with_client ?requests_config ?profile f env =
···161161 | Some _, Some _ ->
162162 Fmt.epr "%a Cannot specify both --api-key and --email. Choose one authentication method.@."
163163 error_style "Error:";
164164- exit 1
164164+ raise (Error.Exit_code 1)
165165166166let login_cmd env fs =
167167 let doc = "Login to an Immich server." in
168168 let info = Cmd.info "login" ~doc in
169169 let login' (style_renderer, level) requests_config server api_key email password profile key_name =
170170 setup_logging_with_config style_renderer level requests_config;
171171- login_action ~requests_config ~server ~api_key ~email ~password ~profile ~key_name env
171171+ Error.wrap (fun () ->
172172+ login_action ~requests_config ~server ~api_key ~email ~password ~profile ~key_name env)
172173 in
173174 Cmd.v info
174175 Term.(const login' $ setup_logging $ requests_config_term fs $ server_arg $ api_key_arg $ email_arg $ password_arg $ profile_arg $ key_name_arg)
···302303 Fmt.epr "%a %a@."
303304 label_style "Available profiles:"
304305 Fmt.(list ~sep:(any ", ") profile_style) profiles;
305305- exit 1
306306+ raise (Error.Exit_code 1)
306307 end
307308308309let profile_switch_cmd env =
+16-4
lib/error.ml
···117117 try f (); 0
118118 with exn -> handle_exn exn
119119120120+(** Exception to signal desired exit code without calling [exit] directly.
121121+ This avoids issues when running inside Eio's event loop. *)
122122+exception Exit_code of int
123123+120124(** Wrap a command action to handle API errors gracefully.
121125122126 This is designed to be used in cmdliner command definitions:
···133137 ]}
134138135139 The wrapper catches API errors and prints a nice message,
136136- then exits with an appropriate code. *)
140140+ then raises [Exit_code] with an appropriate code. This exception
141141+ should be caught by the main program outside the Eio event loop. *)
137142let wrap f =
138143 try f ()
139139- with exn ->
140140- let code = handle_exn exn in
141141- exit code
144144+ with
145145+ | Stdlib.Exit ->
146146+ (* exit() was called somewhere - treat as success *)
147147+ ()
148148+ | Eio.Cancel.Cancelled Stdlib.Exit ->
149149+ (* Eio wraps Exit in Cancelled - treat as success *)
150150+ ()
151151+ | exn ->
152152+ let code = handle_exn exn in
153153+ raise (Exit_code code)
+9-2
lib/error.mli
···53535454(** {1 Exception Handling} *)
55555656+exception Exit_code of int
5757+(** Exception raised to signal a desired exit code.
5858+ This is used instead of calling [exit] directly to avoid issues
5959+ when running inside Eio's event loop. Catch this exception in
6060+ the main program outside the Eio context. *)
6161+5662val handle_exn : exn -> int
5763(** Handle an exception, printing a nice error message if it's an API error.
5864···8288(** Wrap a command action to handle API errors gracefully.
83898490 This is designed to be used in cmdliner command definitions.
8585- Catches API errors, prints a nice message, and exits with
8686- an appropriate code.
9191+ Catches API errors, prints a nice message, and raises {!Exit_code}
9292+ with an appropriate code. The calling code should catch this
9393+ exception outside the Eio event loop.
87948895 Usage:
8996 {[