Skip to content

Commit eb32929

Browse files
committed
refactor: improve JSON conversion with error handling
- Added `toObjectRaw` and `toObjectOption` methods to handle errors during JSON decoding with `Either` and `Option`. - Introduced `shouldLogAsError` flag in `JsonConverter` for customizable logging on decode errors.
1 parent 88734f1 commit eb32929

File tree

4 files changed

+33
-6
lines changed

4 files changed

+33
-6
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ licenses += ("Apache-2.0", url("https://www.apache.org/licenses/LICENSE-2.0.html
2222

2323
crossScalaVersions := Seq("3.7.0", "2.13.16")
2424

25-
scalaVersion := crossScalaVersions.value.head
25+
scalaVersion := crossScalaVersions.value.last
2626

2727
scalacOptions ++= Seq("-deprecation")
2828
//scalacOptions ++= Seq("--Xmax-inlines", "128")

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name" : "mongodb-driver",
33
"organization" : "dev.mongocamp",
4-
"version" : "3.0.6.snapshot",
4+
"version" : "3.0.6",
55
"author" : "info@mongocamp.dev",
66
"license" : "Apache-2.0",
77
"type" : "module",

src/main/scala/dev/mongocamp/driver/mongodb/json/JsonConverter.scala

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import io.circe.syntax._
77
import io.circe.Decoder
88
import io.circe.Encoder
99

10-
class JsonConverter(dropNullValues: Boolean = false) extends CirceSchema with LazyLogging {
10+
class JsonConverter(dropNullValues: Boolean = false, shouldLogAsError: Boolean = false) extends CirceSchema with LazyLogging {
1111

1212
def toJson[A <: Any](s: A)(implicit encoder: Encoder[A]): String = {
1313
if (dropNullValues) {
@@ -28,12 +28,25 @@ class JsonConverter(dropNullValues: Boolean = false) extends CirceSchema with La
2828
readJsonMap(fileContent)
2929
}
3030

31-
def toObject[A](jsonString: String)(implicit decoder: Decoder[A]): A = {
31+
def toObjectRaw[A](jsonString: String)(implicit decoder: Decoder[A]): Either[io.circe.Error, A] = {
3232
val decodeResponse = decode[A](jsonString)
3333
if (decodeResponse.isLeft) {
34-
logger.warn(s"Error while decoding json: ${decodeResponse.left.get}")
34+
if (shouldLogAsError) {
35+
logger.error(s"Error while decoding json: ${decodeResponse.left}")
36+
}
37+
else {
38+
logger.debug(s"Error while decoding json: ${decodeResponse.left}")
39+
}
3540
}
36-
decodeResponse.getOrElse(null.asInstanceOf[A])
41+
decodeResponse
42+
}
43+
44+
def toObject[A](jsonString: String)(implicit decoder: Decoder[A]): A = {
45+
toObjectRaw[A](jsonString).getOrElse(null.asInstanceOf[A])
46+
}
47+
48+
def toObjectOption[A](jsonString: String)(implicit decoder: Decoder[A]): Option[A] = {
49+
toObjectRaw[A](jsonString).toOption
3750
}
3851

3952
}

src/test/scala/dev/mongocamp/driver/mongodb/json/JsonConversionSuite.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
package dev.mongocamp.driver.mongodb.json
2+
import io.circe.ACursor
3+
import io.circe.DecodingFailure
4+
import io.circe.ParsingFailure
5+
import org.typelevel.jawn.IncompleteParseException
26

37
case class HelloWorld(greetings: String, name: String)
48
case class HelloWorld2(greetings: String, name: String, option: Option[HelloWorld], subClass: List[Long])
@@ -32,6 +36,16 @@ class JsonConversionSuite extends munit.FunSuite {
3236
assertEquals(jsonConverter.toObject[Array[Int]]("[1,2]").last, Array(1, 2).last)
3337
}
3438

39+
test("Try to convert invalid strings") {
40+
assertEquals(jsonConverter.toObjectOption[List[String]](""), None)
41+
assertEquals(jsonConverter.toObjectOption[List[String]]("{}"), None)
42+
assertEquals(
43+
jsonConverter.toObjectRaw[List[String]](""),
44+
Left(value = ParsingFailure(message = "exhausted input", underlying = IncompleteParseException(msg = "exhausted input")))
45+
)
46+
assertEquals(jsonConverter.toObjectRaw[List[String]]("{}").left.get.getMessage, "DecodingFailure at : Got value '{}' with wrong type, expecting array")
47+
}
48+
3549
test("Convert Json to Case Class") {
3650
assertEquals(jsonConverter.toObject[HelloWorld]("{\"name\":\"world\", \"greetings\":\"hello\"}"), HelloWorld("hello", "world"))
3751
}

0 commit comments

Comments
 (0)