Matrix protocol in OCaml, Eio specialised
at main 71 lines 2.6 kB view raw
1(** Eio-idiomatic errors for Matrix operations. 2 3 This module provides error types that follow Eio conventions, 4 using [Eio.Io] for IO-related errors and exceptions for 5 exceptional conditions. *) 6 7(** The source type for Matrix IO errors *) 8type err = 9 | Network of string (** Network-level error *) 10 | Http of { status : int; body : string } (** HTTP error response *) 11 | Json of string (** JSON encoding/decoding error *) 12 | Matrix of { 13 errcode : Matrix_client.Error.errcode; 14 error : string; 15 retry_after_ms : int option; 16 } (** Matrix protocol error *) 17 | Not_logged_in (** Operation requires authentication *) 18 | Cancelled (** Operation was cancelled *) 19 20type Eio.Exn.err += E of err 21 22let err e = Eio.Exn.create (E e) 23 24(** Pretty-print an error source *) 25let pp_err fmt = function 26 | Network msg -> Format.fprintf fmt "Network error: %s" msg 27 | Http { status; body } -> Format.fprintf fmt "HTTP %d: %s" status body 28 | Json msg -> Format.fprintf fmt "JSON error: %s" msg 29 | Matrix { errcode; error; _ } -> 30 Format.fprintf fmt "Matrix error %s: %s" 31 (Matrix_client.Error.errcode_to_string errcode) error 32 | Not_logged_in -> Format.fprintf fmt "Not logged in" 33 | Cancelled -> Format.fprintf fmt "Operation cancelled" 34 35let () = Eio.Exn.register_pp (fun fmt -> function 36 | E e -> pp_err fmt e; true 37 | _ -> false) 38 39(** Convert a matrix_client error to an Eio error *) 40let of_client_error = function 41 | Matrix_client.Error.Matrix_error e -> 42 Matrix { 43 errcode = e.errcode; 44 error = e.error; 45 retry_after_ms = e.retry_after_ms; 46 } 47 | Matrix_client.Error.Network_error msg -> Network msg 48 | Matrix_client.Error.Json_error msg -> Json msg 49 | Matrix_client.Error.Http_error { status; body } -> Http { status; body } 50 51(** Raise an Eio.Io exception from a matrix_client error *) 52let raise_client_error e = 53 raise (Eio.Exn.create (E (of_client_error e))) 54 55(** Convert Result-based client operations to Eio-style exceptions *) 56let unwrap = function 57 | Ok v -> v 58 | Error e -> raise_client_error e 59 60(** Check if an error is retryable *) 61let is_retryable = function 62 | Network _ -> true 63 | Http { status; _ } -> status >= 500 || status = 429 64 | Matrix { errcode; _ } -> errcode = Matrix_client.Error.M_LIMIT_EXCEEDED 65 | Json _ | Not_logged_in | Cancelled -> false 66 67(** Get retry delay in seconds from an error, if available *) 68let retry_after = function 69 | Matrix { retry_after_ms = Some ms; _ } -> Some (float_of_int ms /. 1000.0) 70 | Http { status = 429; _ } -> Some 1.0 (* Default retry after *) 71 | _ -> None