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 {
...
}
}