Skip to content

Commit

Permalink
Display json errors instead of uncaught exception (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
gpetiot authored Apr 2, 2024
1 parent dc3fbcc commit b3dac5b
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 31 deletions.
67 changes: 37 additions & 30 deletions lib/contributions.ml
Original file line number Diff line number Diff line change
Expand Up @@ -136,36 +136,43 @@ let of_json ~period:(from, to_) ~user json =
| exception Ppx_yojson_conv_lib.Yojson_conv.Of_yojson_error (exn, _) ->
Error (`Msg (Printexc.to_string exn))
in
let* root =
match user with
| User.Viewer ->
json.data.viewer |> Option.to_result ~none:(`Msg "viewer field missing")
| User.User _ ->
json.data.user |> Option.to_result ~none:(`Msg "user field missing")
in
let username = root.login in
let contribs = root.contributionsCollection in
let items =
let issues = read_issues contribs.issueContributions.nodes in
let issue_comments = read_issue_comments root.issueComments.nodes in
let prs = read_prs contribs.pullRequestContributions.nodes in
let reviews = read_reviews contribs.pullRequestReviewContributions.nodes in
let repos = read_repos contribs.repositoryContributions.nodes in
issues @ issue_comments @ prs @ reviews @ repos
in
let activity =
(* GitHub seems to ignore the time part, so do the filtering here. *)
items
|> List.filter (fun item -> item.date >= from && item.date <= to_)
|> List.fold_left
(fun acc item ->
let items =
Repo_map.find_opt item.repo acc |> Option.value ~default:[]
in
Repo_map.add item.repo (item :: items) acc)
Repo_map.empty
in
Ok { username; activity }
match json.data with
| Some data ->
let* root =
match user with
| User.Viewer ->
data.viewer |> Option.to_result ~none:(`Msg "viewer field missing")
| User.User _ ->
data.user |> Option.to_result ~none:(`Msg "user field missing")
in
let username = root.login in
let contribs = root.contributionsCollection in
let items =
let issues = read_issues contribs.issueContributions.nodes in
let issue_comments = read_issue_comments root.issueComments.nodes in
let prs = read_prs contribs.pullRequestContributions.nodes in
let reviews =
read_reviews contribs.pullRequestReviewContributions.nodes
in
let repos = read_repos contribs.repositoryContributions.nodes in
issues @ issue_comments @ prs @ reviews @ repos
in
let activity =
(* GitHub seems to ignore the time part, so do the filtering here. *)
items
|> List.filter (fun item -> item.date >= from && item.date <= to_)
|> List.fold_left
(fun acc item ->
let items =
Repo_map.find_opt item.repo acc |> Option.value ~default:[]
in
Repo_map.add item.repo (item :: items) acc)
Repo_map.empty
in
Ok { username; activity }
| None ->
Fmt.error_msg "@[%a@]" (Fmt.list Fmt.string)
(List.map (fun x -> x.Json.message) json.errors)

let id url =
match Astring.String.cut ~sep:"/" ~rev:true url with
Expand Down
9 changes: 8 additions & 1 deletion lib/contributions_json_response.ml
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,11 @@ type data = {
[@@deriving yojson]
(** The key is either [viewer] or [user] depending on the request but the value associated is the same. *)

type t = { data : data } [@@deriving yojson]
type error = { message : string }
[@@deriving yojson] [@@yojson.allow_extra_fields]

type t = {
data : data option; [@yojson.option]
errors : error list; [@default []]
}
[@@deriving yojson]
33 changes: 33 additions & 0 deletions test/lib/test_contributions.ml
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,35 @@ let activity_example ~user =
let activity_example_json ~user =
Yojson.Safe.from_string (activity_example ~user)

let error_example =
{|
{
"errors": [
{
"path": [
"query",
"viewer",
"contributionsCollection",
"to"
],
"extensions": {
"code": "argumentLiteralsIncompatible",
"typeName": "Field",
"argumentName": "to"
},
"locations": [
{
"line": 4,
"column": 5
}
],
"message": "Error."
}
]
} |}

let error_example_json = Yojson.Safe.from_string error_example

let contributions_example1 ~user =
let open Contributions in
{
Expand Down Expand Up @@ -493,6 +522,10 @@ let test_of_json =
username = user |> or_viewer;
activity = Contributions.Repo_map.empty;
}));
(let user = User.User "gpetiot" in
make_test "errors"
~period:("2024-02-27T12:05:04Z", "2024-03-13T11:09:56Z")
~user error_example_json ~expected:(Fmt.error_msg "Error."));
]

let test_is_empty =
Expand Down

0 comments on commit b3dac5b

Please sign in to comment.