CodexBloom - Programming Q&A Platform

How to handle nested futures with Scala 3.1 and properly transform responses?

šŸ‘€ Views: 0 šŸ’¬ Answers: 1 šŸ“… Created: 2025-07-15
scala futures error-handling Scala

I'm optimizing some code but I'm working on a personal project and I've looked through the documentation and I'm still confused about I'm working on a personal project and I'm working on a Scala 3.1 application that makes use of nested futures to fetch data from a REST API. The structure of the API response is a bit complex, and I'm having trouble properly chaining my futures and transforming the results as needed. I have an initial function that fetches user data, which returns a `Future[User]`, and then I need to fetch related posts for that user, which returns another `Future[List[Post]]`. Here's the code I have: ```scala import scala.concurrent.{Future, ExecutionContext} import scala.util.{Success, Failure} case class User(id: Int, name: String) case class Post(id: Int, userId: Int, title: String) object ApiService { def fetchUser(userId: Int)(implicit ec: ExecutionContext): Future[User] = { // Simulate an API call Future.successful(User(userId, "John Doe")) } def fetchPostsByUser(userId: Int)(implicit ec: ExecutionContext): Future[List[Post]] = { // Simulate another API call Future.successful(List(Post(1, userId, "Post 1"), Post(2, userId, "Post 2"))) } } object Main extends App { implicit val ec: ExecutionContext = ExecutionContext.global val userId = 1 val result: Future[List[Post]] = ApiService.fetchUser(userId).flatMap { user => ApiService.fetchPostsByUser(user.id) } result.onComplete { case Success(posts) => println(s"Fetched posts: $posts") case Failure(exception) => println(s"Failed to fetch posts: ${exception.getMessage}") } } ``` However, when I run this, I receive a `Failure(java.util.concurrent.CompletionException: java.lang.RuntimeException: Simulated failure)` as an error. The `fetchPostsByUser` function might fail under certain conditions (like if the API is down), but I’m not sure how to properly handle this case. I've tried using `recover` on the future, but it doesn't seem to catch the exception properly. How can I ensure that I can handle errors gracefully in this nested future structure and still transform the results as needed without losing the context of the original error? I'd really appreciate any guidance on this. This is part of a larger service I'm building. I recently upgraded to Scala 3.9. How would you solve this?