Skip to content

Commit 2823fb4

Browse files
committed
use code defined in error case in the server
1 parent cd55eef commit 2823fb4

File tree

3 files changed

+29
-13
lines changed

3 files changed

+29
-13
lines changed

src/common/service.ml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ type ('args, 'input, 'output, 'error, 'security) t = {
5555
}
5656

5757
let make =
58-
fun ?(meth : Meth.t =`GET) ?(params=[]) ?(security=[]) ?(errors=[])
58+
fun ?(meth : Meth.t =`GET) ?(params=[]) ?(security=[]) ?(errors=[])
5959
?(access_control=[]) ~input ~output path ->
6060
{ path ; input ; output; errors; meth; params; security; access_control }
6161

@@ -75,3 +75,14 @@ let params s = s.params
7575
let access_control s = s.access_control
7676

7777
let error s ~code = Err.get ~code s.errors
78+
79+
let errors_handler s e =
80+
let rec aux = function
81+
| [] ->
82+
let Err.Case {encoding; code; select; _} = Err.catch_all_error_case () in
83+
code, EzEncoding.construct encoding (Option.get (select e))
84+
| Err.Case {encoding; code; select; _} :: tl ->
85+
match select e with
86+
| None -> aux tl
87+
| Some x -> code, EzEncoding.construct encoding x in
88+
aux s.errors

src/server/answer.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ type 'a t = {
1414
headers : (string * string) list;
1515
}
1616

17-
let return ?(code=200) ?(headers=[]) body = Lwt.return {code; body; headers}
17+
let return ?(code= -1) ?(headers=[]) body = Lwt.return {code; body; headers}
1818

1919
let not_found () = return ~code:404 ""
2020

src/server/directory.ml

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ let rec resolve :
9292
(resolved_directory, lookup_error) result Lwt.t =
9393
fun prefix dir args path ->
9494
match path, dir with
95-
| [], dir ->
95+
| [], dir ->
9696
Lwt.return_ok (Dir (dir, args))
9797
| _name :: _path, { subdirs = None, None; _ } -> Lwt.return_error `Not_found
9898
| name :: path, { subdirs = Some static, None; _ } ->
@@ -116,31 +116,36 @@ let rec resolve :
116116
`Cannot_parse (arg.Arg.description, msg, name :: prefix)
117117

118118
(* Note : headers are merged with predefined headers *)
119-
let io_to_answer : type a. code:int -> headers:(string * string) list -> a io -> a -> string Answer.t =
120-
fun ~code ~headers io body ->
119+
let io_to_answer : type a. code:int -> headers:(string * string) list -> a io -> a -> string Answer.t =
120+
fun ~code ~headers io body ->
121121
match io with
122-
| Empty -> {Answer.code; body=""; headers}
122+
| Empty ->
123+
let code = if code = -1 then 204 else code in
124+
{Answer.code; body=""; headers}
123125
| Raw l ->
124126
let content_type = match l with
125127
| [] -> "application/octet-stream"
126128
| h :: _ -> Mime.to_string h in
129+
let code = if code = -1 then 200 else code in
127130
{Answer.code; body; headers=("content-type", content_type)::headers}
128131
| Json enc ->
132+
let code = if code = -1 then 200 else code in
129133
{Answer.code; body = EzEncoding.construct enc body;
130134
headers=("content-type", "application/json")::headers}
131135

132136
let ser_handler :
133-
type i o e. ?content_type:string -> access_control:(string * string) list
137+
type i o e. ?content_type:string -> access_control:(string * string) list
134138
-> ('a -> i -> (o, e) result Answer.t Lwt.t) -> 'a ->
135-
i io -> o io -> e Json_encoding.encoding ->
139+
i io -> o io -> (e -> int * string) ->
136140
string -> (string Answer.t, handler_error) result Lwt.t =
137141
fun ?content_type ~access_control handler args input output errors ->
138-
let handle_result {Answer.code; body; headers} =
142+
let handle_result {Answer.code; body; headers} =
139143
match body with
140144
| Ok o -> io_to_answer ~code ~headers:(headers @ access_control) output o
141145
| Error e ->
142-
{Answer.code; body = EzEncoding.construct errors e;
143-
headers=("content-type", "application/json")::access_control }
146+
let c, body = errors e in
147+
let code = if code = -1 then c else code in
148+
{Answer.code; body; headers=("content-type", "application/json")::access_control }
144149
in
145150
match input with
146151
| Empty -> (fun _ ->
@@ -194,7 +199,7 @@ let lookup ?meth ?content_type dir r path : (lookup_ok, lookup_error) result Lwt
194199
(* Todo : combine access control headers correctly. *)
195200
let access_control = List.fold_left (fun acc (_,rs) -> match rs with
196201
| Http {service; _} when acc = [] -> Service.access_control service
197-
| _ -> acc) [] l in
202+
| _ -> acc) [] l in
198203
let meths = Meth.headers @@ List.map fst l in
199204
let sec_set = List.fold_left (fun acc (_, rs) -> match rs with
200205
| Http {service; _} -> Security.StringSet.union acc (Security.headers (Service.security service))
@@ -207,7 +212,7 @@ let lookup ?meth ?content_type dir r path : (lookup_ok, lookup_error) result Lwt
207212
| _, Some (Http {service; handler}) ->
208213
let input = Service.input service in
209214
let output = Service.output service in
210-
let errors = Service.errors_encoding service in
215+
let errors = Service.errors_handler service in
211216
let access_control = Service.access_control service in
212217
let h = ser_handler ?content_type ~access_control handler args input output errors in
213218
Lwt.return_ok @@ `http h

0 commit comments

Comments
 (0)