Skip to content

Commit 3130bca

Browse files
committed
Merge pull request #14 from codacy/handle-json-failures
Handle JSON parsing failures
2 parents b191fe8 + 8dc76f7 commit 3130bca

File tree

3 files changed

+41
-16
lines changed

3 files changed

+41
-16
lines changed

src/main/scala/com/codacy/client/bitbucket/PullRequest.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ object PullRequest {
5858
(__ \ "destination" \ "repository" \ "full_name").read[String] and
5959
(__ \ "destination" \ "branch" \ "name").read[String] and
6060
(__ \ "destination" \ "commit" \ "hash").read[String] and
61+
// TODO: (__ \ "destination" \ "commit" \ "hash").read[Option[String]] and
6162
(__ \ "links").read[Map[String, Map[String, String]]].map(parseLinks)
62-
)(PullRequest.apply _)
63+
) (PullRequest.apply _)
6364

6465
private def parseLinks(links: Map[String, Map[String, String]]): Seq[ApiUrl] = {
6566
(for {

src/main/scala/com/codacy/client/bitbucket/client/BitbucketClient.scala

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ class BitbucketClient(key: String, secretKey: String, token: String, secretToken
2626
*/
2727
def execute[T](request: Request[T])(implicit reader: Reads[T]): RequestResponse[T] = {
2828
get(request.url) match {
29-
case Right(json) => RequestResponse(json.asOpt[T])
30-
case Left(error) => RequestResponse(None, error.detail, hasError = true)
29+
case Right(json) => json.validate[T].fold(_ => FailedResponse(s"Failed to parse json: $json"), a => SuccessfulResponse(a))
30+
case Left(error) => FailedResponse(error.detail)
3131
}
3232
}
3333

@@ -40,14 +40,14 @@ class BitbucketClient(key: String, secretKey: String, token: String, secretToken
4040
val nextPage = (json \ "next").asOpt[String]
4141
val nextRepos = nextPage.map {
4242
nextUrl =>
43-
executePaginated(Request(nextUrl, request.classType)).value.getOrElse(Seq())
44-
}.getOrElse(Seq())
43+
executePaginated(Request(nextUrl, request.classType))
44+
}.getOrElse(SuccessfulResponse(Seq.empty))
4545

46-
val values = (json \ "values").asOpt[Seq[T]].getOrElse(Seq())
47-
RequestResponse(Some(values ++ nextRepos))
46+
val values = (json \ "values").validate[Seq[T]].fold(_ => FailedResponse(s"Failed to parse json: $json"), a => SuccessfulResponse(a))
47+
RequestResponse.apply(values, nextRepos)
4848

4949
case Left(error) =>
50-
RequestResponse[Seq[T]](None, error.detail, hasError = true)
50+
FailedResponse(error.detail)
5151
}
5252
}
5353

@@ -66,13 +66,13 @@ class BitbucketClient(key: String, secretKey: String, token: String, secretToken
6666

6767
val jsValue = parseJson(body)
6868
jsValue match {
69-
case Right(responseObj) =>
70-
RequestResponse(responseObj.asOpt[T])
69+
case Right(json) =>
70+
json.validate[T].fold(_ => FailedResponse(s"Failed to parse json: $json"), a => SuccessfulResponse(a))
7171
case Left(message) =>
72-
RequestResponse[T](None, message = message.detail, hasError = true)
72+
FailedResponse(message.detail)
7373
}
7474
} else {
75-
RequestResponse[T](None, result.statusText, hasError = true)
75+
FailedResponse(result.statusText)
7676
}
7777

7878
value
@@ -103,9 +103,9 @@ class BitbucketClient(key: String, secretKey: String, token: String, secretToken
103103
val result = Await.result(jpromise, requestTimeout)
104104

105105
val value = if (Seq(HTTPStatusCodes.OK, HTTPStatusCodes.CREATED, HTTPStatusCodes.NO_CONTENT).contains(result.status)) {
106-
RequestResponse(Option(true))
106+
SuccessfulResponse(true)
107107
} else {
108-
RequestResponse[Boolean](None, result.statusText, hasError = true)
108+
FailedResponse(result.statusText)
109109
}
110110

111111
value
@@ -157,7 +157,7 @@ class BitbucketClient(key: String, secretKey: String, token: String, secretToken
157157
|
158158
|${getFullStackTrace(error)}
159159
""".stripMargin
160-
RequestResponse[T](None, statusMessage, hasError = true)
160+
FailedResponse(statusMessage)
161161
}
162162
}
163163

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
11
package com.codacy.client.bitbucket.client
22

3-
case class RequestResponse[T](value: Option[T], message: String = "", hasError: Boolean = false)
3+
sealed trait RequestResponse[+A]
4+
5+
case class SuccessfulResponse[A](value: A) extends RequestResponse[A]
6+
7+
case class FailedResponse(message: String) extends RequestResponse[Nothing]
8+
9+
object RequestResponse {
10+
11+
def success[A](a: A): RequestResponse[A] = SuccessfulResponse(a)
12+
13+
def failure[A](message: String): RequestResponse[A] = FailedResponse(message: String)
14+
15+
def apply[A](r1: RequestResponse[Seq[A]], r2: RequestResponse[Seq[A]]): RequestResponse[Seq[A]] = {
16+
r1 match {
17+
case SuccessfulResponse(v1) =>
18+
r2 match {
19+
case SuccessfulResponse(v2) =>
20+
SuccessfulResponse(v1 ++ v2)
21+
case f@FailedResponse(_) => f
22+
}
23+
case f@FailedResponse(_) => f
24+
}
25+
}
26+
27+
}

0 commit comments

Comments
 (0)