Errors of one selection of a batch #
GitHub answers a query whose aliased selections fail one by one with the
selections it could resolve under data and an errors member, each error
naming the alias it is about as the first step of its path
(GraphQL, section 7.1.2).
A repository GitHub does not know is null with an error of type
NOT_FOUND; one it refuses to show, such as one behind an organisation's
SAML enforcement, is null with an error of type FORBIDDEN. The two need
different handling: the first is gone, the second should be asked again.
A stub transport answers four aliases: one resolved, one not found, one forbidden, and one whose nested field failed.
# let with_client f =
let answer =
{|{"data":{"a0":{"id":"R_1","nameWithOwner":"ocaml/dune"},
"a1":null,"a2":null,"a3":{"id":"R_3","parent":null}},
"errors":[
{"type":"NOT_FOUND","path":["a1"],
"message":"Could not resolve to a Repository with the name 'ocaml/gone'."},
{"type":"FORBIDDEN","path":["a2"],
"message":"Resource protected by organization SAML enforcement."},
{"path":["a3","parent"],
"message":"Something went wrong while executing your query."}]}|}
in
Eio_mock.Backend.run @@ fun () ->
let clock = Eio_mock.Clock.make () in
let store = Cas_store.in_memory ~clock () in
let transport ~headers:_ _ =
Ok (Github_query.response ~status:200 answer)
in
f (Github_query.v ~clock ~store ~token:"t" transport);;
val with_client : (Github_query.t -> 'a) -> 'a = <fun>
Each repository gets its own answer: a value, Not_found, or the errors
about its alias alone.
# let show = function
| Ok j -> "ok " ^ Json.Value.to_string j
| Error Github_query.Not_found -> "not found"
| Error (Github_query.Graphql es) -> "errors " ^ Json.Value.to_canonical es
| Error e -> Fmt.str "%a" Github_query.pp_error e;;
val show : (Json.t, Github_query.error) result -> string = <fun>
# with_client (fun gq ->
Github_query.batch gq ~policy:(Cas_store.Policy.Snapshot "d")
(fun n -> Fmt.str "repository(owner:\"ocaml\" name:%S){id nameWithOwner}" n)
[ "dune"; "gone"; "saml"; "opam" ]
|> List.map (fun (n, r) -> (n, show r)));;
- : (string * string) list =
[("dune", "ok {\"id\":\"R_1\",\"nameWithOwner\":\"ocaml/dune\"}");
("gone", "not found");
("saml",
"errors [{\"message\":\"Resource protected by organization SAML enforcement.\",\"path\":[\"a2\"],\"type\":\"FORBIDDEN\"}]");
("opam",
"errors [{\"message\":\"Something went wrong while executing your query.\",\"path\":[\"a3\",\"parent\"]}]")]
A probe tells a repository GitHub does not know, Ok None, from one whose
probe failed, an error.
# with_client (fun gq ->
Github_query.Probe.repos gq ~policy:(Cas_store.Policy.Snapshot "d")
[ ("ocaml", "dune"); ("ocaml", "gone"); ("ocaml", "saml") ]
|> List.map (fun ((_, n), r) ->
( n,
match r with
| Ok None -> "gone"
| Ok (Some _) -> "seen"
| Error _ -> "unknown" )));;
- : (string * string) list =
[("dune", "seen"); ("gone", "gone"); ("saml", "unknown")]