From 9724bef7a6b987d709634d39923b27a115dbd8e1 Mon Sep 17 00:00:00 2001
From: Felipe D'Abrantes <felidabrantes@gmail>
Date: Sat, 8 Apr 2023 00:18:37 +0100
Subject: [PATCH] Add better exception handling for unknown Dailies

---
 .../feed-service/app/controllers/DailyController.scala     | 3 ++-
 backend-services/feed-service/app/models/Daily.scala       | 7 +++++--
 .../app/models/exceptions/NotFoundException.scala          | 3 +++
 .../feed-service/app/repositories/Repository.scala         | 6 +++---
 4 files changed, 13 insertions(+), 6 deletions(-)
 create mode 100644 backend-services/feed-service/app/models/exceptions/NotFoundException.scala

diff --git a/backend-services/feed-service/app/controllers/DailyController.scala b/backend-services/feed-service/app/controllers/DailyController.scala
index 0217dc2e..3dc422bd 100644
--- a/backend-services/feed-service/app/controllers/DailyController.scala
+++ b/backend-services/feed-service/app/controllers/DailyController.scala
@@ -5,7 +5,7 @@ import play.api.mvc._
 import play.api.libs.json.JsValue
 
 import models.{Daily}
-import models.exceptions.ConflictException
+import models.exceptions.{ConflictException, NotFoundException}
 
 import scala.concurrent.TimeoutException
 import org.bson.types.ObjectId
@@ -94,6 +94,7 @@ class DailyController @Inject()(val controllerComponents: ControllerComponents)
     } catch {
         case _: TimeoutException => BadRequest("Request timed out")
         case ex: ConflictException => BadRequest(ex.getMessage())
+        case ex: NotFoundException => BadRequest(ex.getMessage())
         case _: Throwable => BadRequest("Exception raised")
     }
   }
diff --git a/backend-services/feed-service/app/models/Daily.scala b/backend-services/feed-service/app/models/Daily.scala
index db1c1098..a81a6368 100644
--- a/backend-services/feed-service/app/models/Daily.scala
+++ b/backend-services/feed-service/app/models/Daily.scala
@@ -1,7 +1,7 @@
 package models
 
 import repositories.{DailyRepository}
-import models.exceptions.{ConflictException}
+import models.exceptions.{ConflictException, NotFoundException}
 
 import scala.concurrent.ExecutionContext.Implicits.global
 import scala.concurrent.{Future, Await}
@@ -66,8 +66,11 @@ object Daily {
 
     def likeAsync(dailyId: ObjectId, likerId: ObjectId, timeout: Int = 4): Unit = {
         val result: Future[Unit] = for {
-            daily: Daily  <- dailyRepo.getById(dailyId)
+            oDaily: Option[Daily]  <- dailyRepo.getById(dailyId)
             like: Unit <- {
+                // Check daily with given ID exists
+                val daily = if (oDaily.isEmpty) throw new NotFoundException("No daily with given ID.") else oDaily.get
+                
                 // Check user has not already liked Daily
                 if (daily.usersLiked.contains(likerId)) throw new ConflictException("User has already liked this Daily.")
 
diff --git a/backend-services/feed-service/app/models/exceptions/NotFoundException.scala b/backend-services/feed-service/app/models/exceptions/NotFoundException.scala
new file mode 100644
index 00000000..edd62c3f
--- /dev/null
+++ b/backend-services/feed-service/app/models/exceptions/NotFoundException.scala
@@ -0,0 +1,3 @@
+package models.exceptions
+
+case class NotFoundException(message: String) extends Exception(message)
diff --git a/backend-services/feed-service/app/repositories/Repository.scala b/backend-services/feed-service/app/repositories/Repository.scala
index ee79ca59..4cb446e3 100644
--- a/backend-services/feed-service/app/repositories/Repository.scala
+++ b/backend-services/feed-service/app/repositories/Repository.scala
@@ -55,11 +55,11 @@ class Repository[T: ClassTag](databaseName: String, collectionName: String) {
     /**
      * Gets a record with the given ID in the collection.
      * 
-     * @return A Future containing a sequence of matching documents.
+     * @return A Future containing an optional matching document.
      */
-    def getById(id: ObjectId): Future[T] = {
+    def getById(id: ObjectId): Future[Option[T]] = {
         val filter: Bson = Filters.equal[ObjectId]("_id", id)
-        MongoConnection.find[T](collection, filter).map(_.head)
+        MongoConnection.find[T](collection, filter).map(_.headOption)
     }
 
     /**
-- 
GitLab