Skip to content

Instantly share code, notes, and snippets.

@nbenns
Created January 2, 2019 23:15
Show Gist options
  • Save nbenns/6dcc784055aa8dc1ea70a95fa57b9600 to your computer and use it in GitHub Desktop.
Save nbenns/6dcc784055aa8dc1ea70a95fa57b9600 to your computer and use it in GitHub Desktop.
Composing Errors with Coproduct
import shapeless.{ :+:, CNil, Coproduct }
import shapeless._
val error1 = Coproduct[IllegalArgumentException :+: CNil](new IllegalArgumentException)
val error2 = Coproduct[NumberFormatException :+: CNil](new NumberFormatException)
type MyError = IllegalArgumentException :+: NumberFormatException :+: CNil
object MyErrorHandler extends Poly1 {
implicit def caseConfigNotFoundException: Case.Aux[IllegalArgumentException, String] =
at[IllegalArgumentException](e => "bad args")
implicit def caseWrongConfigException: Case.Aux[NumberFormatException, String] =
at[NumberFormatException](e => "bad num")
}
def blah(): Either[IllegalArgumentException :+: CNil, String] = Left(error1)
def blim(): Either[NumberFormatException :+: CNil, String] = Left(error2)
val a: Either[IllegalArgumentException :+: CNil, String] = blah()
val b: Either[NumberFormatException :+: CNil, String] = blim()
val c: Either[MyError, String] = for {
a1 <- a.left.map(_.embed[MyError])
b1 <- b.left.map(_.embed[MyError])
} yield a1 + b1
val out: String = c match {
case Left(err) => err.fold(MyErrorHandler)
case Right(str) => str
}
println(out)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment