Open error model in Scala Cats applications

Introduction In a previous article, I demonstrated a simple application using Cats and Cats Effect. We used an approach where errors were not explicitly represented in the API types.This approach works well for small services with simple APIs. Our final service was defined like this: 1 2 3 4 5 6 7 8 9 trait UserService[F[_]] { def createUser(userCreate: UserCreate): F[UserResponse] def login(loginRequest: LoginRequest): F[AuthResponse] def refreshTokens(refreshToken: String): F[AuthResponse] def getUser(id: UUID): F[UserResponse] def updateUserStatus(id: UUID, isActive: Boolean): F[Boolean] def validateUserForAccess(token: String): F[User] def listActiveUsers(offset: Long, count: Long): F[List[UserResponse]] } We used the Raise/Handle approach, and our error model was defined as a sealed trait hierarchy (though one could use enums as well). ...

November 13, 2025 · 10 min · 1919 words · Me