I have a simple slick query which run on database:
def method(): Future[Either[Error, MyCustomDTO]] =
OptionT(database.run(query))
.map(MyCustomDTO(_))
.toRight(dataNotFound())
.value
The problem is with .toRight. I would like to map it to sifferent errors depends on what was returned by database. E.g.
case FOREIGN_KEY_CONSTRAINT_VIOLATION.toString => constraintError()
case UNIQUE_CONSTRAINT_VIOLATION.toString => uniqueError()
case _ => dataNotFound()
I tried to do match case in .toRight(), but it does not work:
.toRight(error => error.asInstanceOf[PSQLException].getSQLState match { .... })
I'm wondering what is the best possibility to map different errors here in a correct way?
Take a look at the signature of
toRight(...)both of these take by-name parameter - on other words they are special syntax of
() => ...where() => ...in definition and...()in application are inserted for you. Why? Because ontoLeft/toRightinOptionTassume that you are handling the kind of error that is expresses byOption- that isNone. Since there is no need to pass_: None.type =>it uses by-name parameter instead.If you want to handle the error you have to handle it inside
F[A]- by providing the right type class (ApplicativeError[F, Throwable]/MonadError[F, Throwable]) which would allow callinghandleError/handleErrorWith/redeemetcsince your
Fseem to beFuture, and since you have it wrapped inOptionTI guess it worked better if you did something like:You could also give up on
OptionTand do: