Matrix protocol in OCaml, Eio specialised
1type errcode =
2 | M_FORBIDDEN
3 | M_UNKNOWN_TOKEN
4 | M_MISSING_TOKEN
5 | M_BAD_JSON
6 | M_NOT_JSON
7 | M_NOT_FOUND
8 | M_LIMIT_EXCEEDED
9 | M_UNRECOGNIZED
10 | M_UNKNOWN
11 | M_UNAUTHORIZED
12 | M_USER_DEACTIVATED
13 | M_USER_IN_USE
14 | M_INVALID_USERNAME
15 | M_ROOM_IN_USE
16 | M_INVALID_ROOM_STATE
17 | M_THREEPID_IN_USE
18 | M_THREEPID_NOT_FOUND
19 | M_THREEPID_AUTH_FAILED
20 | M_THREEPID_DENIED
21 | M_SERVER_NOT_TRUSTED
22 | M_UNSUPPORTED_ROOM_VERSION
23 | M_INCOMPATIBLE_ROOM_VERSION
24 | M_BAD_STATE
25 | M_GUEST_ACCESS_FORBIDDEN
26 | M_CAPTCHA_NEEDED
27 | M_CAPTCHA_INVALID
28 | M_MISSING_PARAM
29 | M_INVALID_PARAM
30 | M_TOO_LARGE
31 | M_EXCLUSIVE
32 | M_RESOURCE_LIMIT_EXCEEDED
33 | M_CANNOT_LEAVE_SERVER_NOTICE_ROOM
34 | M_WEAK_PASSWORD
35 | M_UNKNOWN_CODE of string
36
37let errcode_to_string = function
38 | M_FORBIDDEN -> "M_FORBIDDEN"
39 | M_UNKNOWN_TOKEN -> "M_UNKNOWN_TOKEN"
40 | M_MISSING_TOKEN -> "M_MISSING_TOKEN"
41 | M_BAD_JSON -> "M_BAD_JSON"
42 | M_NOT_JSON -> "M_NOT_JSON"
43 | M_NOT_FOUND -> "M_NOT_FOUND"
44 | M_LIMIT_EXCEEDED -> "M_LIMIT_EXCEEDED"
45 | M_UNRECOGNIZED -> "M_UNRECOGNIZED"
46 | M_UNKNOWN -> "M_UNKNOWN"
47 | M_UNAUTHORIZED -> "M_UNAUTHORIZED"
48 | M_USER_DEACTIVATED -> "M_USER_DEACTIVATED"
49 | M_USER_IN_USE -> "M_USER_IN_USE"
50 | M_INVALID_USERNAME -> "M_INVALID_USERNAME"
51 | M_ROOM_IN_USE -> "M_ROOM_IN_USE"
52 | M_INVALID_ROOM_STATE -> "M_INVALID_ROOM_STATE"
53 | M_THREEPID_IN_USE -> "M_THREEPID_IN_USE"
54 | M_THREEPID_NOT_FOUND -> "M_THREEPID_NOT_FOUND"
55 | M_THREEPID_AUTH_FAILED -> "M_THREEPID_AUTH_FAILED"
56 | M_THREEPID_DENIED -> "M_THREEPID_DENIED"
57 | M_SERVER_NOT_TRUSTED -> "M_SERVER_NOT_TRUSTED"
58 | M_UNSUPPORTED_ROOM_VERSION -> "M_UNSUPPORTED_ROOM_VERSION"
59 | M_INCOMPATIBLE_ROOM_VERSION -> "M_INCOMPATIBLE_ROOM_VERSION"
60 | M_BAD_STATE -> "M_BAD_STATE"
61 | M_GUEST_ACCESS_FORBIDDEN -> "M_GUEST_ACCESS_FORBIDDEN"
62 | M_CAPTCHA_NEEDED -> "M_CAPTCHA_NEEDED"
63 | M_CAPTCHA_INVALID -> "M_CAPTCHA_INVALID"
64 | M_MISSING_PARAM -> "M_MISSING_PARAM"
65 | M_INVALID_PARAM -> "M_INVALID_PARAM"
66 | M_TOO_LARGE -> "M_TOO_LARGE"
67 | M_EXCLUSIVE -> "M_EXCLUSIVE"
68 | M_RESOURCE_LIMIT_EXCEEDED -> "M_RESOURCE_LIMIT_EXCEEDED"
69 | M_CANNOT_LEAVE_SERVER_NOTICE_ROOM -> "M_CANNOT_LEAVE_SERVER_NOTICE_ROOM"
70 | M_WEAK_PASSWORD -> "M_WEAK_PASSWORD"
71 | M_UNKNOWN_CODE s -> s
72
73let errcode_of_string = function
74 | "M_FORBIDDEN" -> M_FORBIDDEN
75 | "M_UNKNOWN_TOKEN" -> M_UNKNOWN_TOKEN
76 | "M_MISSING_TOKEN" -> M_MISSING_TOKEN
77 | "M_BAD_JSON" -> M_BAD_JSON
78 | "M_NOT_JSON" -> M_NOT_JSON
79 | "M_NOT_FOUND" -> M_NOT_FOUND
80 | "M_LIMIT_EXCEEDED" -> M_LIMIT_EXCEEDED
81 | "M_UNRECOGNIZED" -> M_UNRECOGNIZED
82 | "M_UNKNOWN" -> M_UNKNOWN
83 | "M_UNAUTHORIZED" -> M_UNAUTHORIZED
84 | "M_USER_DEACTIVATED" -> M_USER_DEACTIVATED
85 | "M_USER_IN_USE" -> M_USER_IN_USE
86 | "M_INVALID_USERNAME" -> M_INVALID_USERNAME
87 | "M_ROOM_IN_USE" -> M_ROOM_IN_USE
88 | "M_INVALID_ROOM_STATE" -> M_INVALID_ROOM_STATE
89 | "M_THREEPID_IN_USE" -> M_THREEPID_IN_USE
90 | "M_THREEPID_NOT_FOUND" -> M_THREEPID_NOT_FOUND
91 | "M_THREEPID_AUTH_FAILED" -> M_THREEPID_AUTH_FAILED
92 | "M_THREEPID_DENIED" -> M_THREEPID_DENIED
93 | "M_SERVER_NOT_TRUSTED" -> M_SERVER_NOT_TRUSTED
94 | "M_UNSUPPORTED_ROOM_VERSION" -> M_UNSUPPORTED_ROOM_VERSION
95 | "M_INCOMPATIBLE_ROOM_VERSION" -> M_INCOMPATIBLE_ROOM_VERSION
96 | "M_BAD_STATE" -> M_BAD_STATE
97 | "M_GUEST_ACCESS_FORBIDDEN" -> M_GUEST_ACCESS_FORBIDDEN
98 | "M_CAPTCHA_NEEDED" -> M_CAPTCHA_NEEDED
99 | "M_CAPTCHA_INVALID" -> M_CAPTCHA_INVALID
100 | "M_MISSING_PARAM" -> M_MISSING_PARAM
101 | "M_INVALID_PARAM" -> M_INVALID_PARAM
102 | "M_TOO_LARGE" -> M_TOO_LARGE
103 | "M_EXCLUSIVE" -> M_EXCLUSIVE
104 | "M_RESOURCE_LIMIT_EXCEEDED" -> M_RESOURCE_LIMIT_EXCEEDED
105 | "M_CANNOT_LEAVE_SERVER_NOTICE_ROOM" -> M_CANNOT_LEAVE_SERVER_NOTICE_ROOM
106 | "M_WEAK_PASSWORD" -> M_WEAK_PASSWORD
107 | s -> M_UNKNOWN_CODE s
108
109let errcode_jsont =
110 Jsont.of_of_string ~kind:"errcode"
111 ~enc:errcode_to_string
112 (fun s -> Ok (errcode_of_string s))
113
114type matrix_error = {
115 errcode : errcode;
116 error : string;
117 retry_after_ms : int option;
118 soft_logout : bool option;
119}
120
121let matrix_error_jsont =
122 Jsont.Object.(
123 map (fun errcode error retry_after_ms soft_logout ->
124 { errcode; error; retry_after_ms; soft_logout })
125 |> mem "errcode" errcode_jsont ~enc:(fun e -> e.errcode)
126 |> mem "error" Jsont.string ~dec_absent:"" ~enc:(fun e -> e.error)
127 |> opt_mem "retry_after_ms" Jsont.int ~enc:(fun e -> e.retry_after_ms)
128 |> opt_mem "soft_logout" Jsont.bool ~enc:(fun e -> e.soft_logout)
129 |> finish)
130
131type t =
132 | Matrix_error of matrix_error
133 | Network_error of string
134 | Json_error of string
135 | Http_error of { status : int; body : string }
136
137type 'a result = ('a, t) Stdlib.result
138
139let pp fmt = function
140 | Matrix_error e ->
141 Format.fprintf fmt "Matrix error %s: %s"
142 (errcode_to_string e.errcode) e.error
143 | Network_error s ->
144 Format.fprintf fmt "Network error: %s" s
145 | Json_error s ->
146 Format.fprintf fmt "JSON error: %s" s
147 | Http_error { status; body } ->
148 Format.fprintf fmt "HTTP error %d: %s" status body
149
150let to_string e =
151 Format.asprintf "%a" pp e