Home > front end >  Scala Throwable raised inside for comprehension yield block is expecting custom ExceptionHandler
Scala Throwable raised inside for comprehension yield block is expecting custom ExceptionHandler

Time:08-28

My function signature is like below

def createEntity(json: Json): Either[Throwable, T] = {
 json.as[T] flatMap { data =>
  for {
     a_id <- root.a_id.string.getOption(json).orThrowable("Missing a id")
     b_id <- root.b_id.string.getOption(json).orThrowable("Missing b id")
     data <- getData(b_id)
  } yield { 
      if (checkIfExists(b_id).size > 0) {
        throw new Error(s"Data for $b_id already exists")
      }
      ...
   }
 }
}

Now this function is called as part of an Http call.

 post {
          complete(StatusCodes.InternalServerError, createEntity(myJson))
      }

The problem I am seeing with this is Throwable part of yield block is not getting returned as Http response rather I am getting

Error during processing of request: 'Data for someID already exists'. Completing with 500 Internal Server Error response. To change default exception handling behavior, provide a custom ExceptionHandler.

But the other Throwable while json parsing like "Missing a id" , "Missing b id" is working fine as response .

CodePudding user response:

for-comprehension is not a try-catch block. Unless Either's map/flatMap/foreach would catch (they aren't) exception transparently will get thrown out of each nested function.

If you wanted to do a validation you should have done:

def createEntity(json: Json): Either[Throwable, T] = {
  for {
    a_id <- root.a_id.string.getOption(json).orThrowable("Missing a id")
    b_id <- root.b_id.string.getOption(json).orThrowable("Missing b id")
    data <- getData(b_id)
    _ <- Either.cond(checkIfExists(b_id).isEmpty, (), new Error(s"Data for $b_id already exists"))
  } yield { 
    ...
  }
}
  • Related