This is a follow-up for my previous question.
Suppose I have functions foo
, bar
, and qux
that raise exceptions.
def foo(x: Int, y: Int, z: Int): String = ...
def bar(s: String): String = ...
def qux(t: String): String = ...
I am composing them as follows:
def myFun(x: Int, y: Int, z: Int): String = {
val s = foo(x, y, z)
val t = bar(s)
qux(t)
}
What if bar
raises an exception ? If the exception does not contain s
I cannot understand what happened. I probably need to add s
to that exception. (The same applies to Either
, \/
, etc.)
So I am defining an exception, which "captures" the arguments:
case class MyException(e: Exception, args: Any*) extends Exception(e)
and writing myFun
as follows:
def myFun(x: Int, y: Int, z: Int): String = {
def myFoo(x: Int, y: Int, z: Int) = try foo(x, y, z) catch {
case NonFatal(e: Exception) => throw MyException(e, x, y, z)
}
def myBar(s: String) = try bar(s) catch {
case NonFatal(e: Exception) => throw MyException(e, s)
}
def myQux(t: String) = try qux(t) catch {
case NonFatal(e: Exception) => throw MyException(e, t)
}
val s = myFoo(x, y, z)
val t = myBar(s)
myQux(t)
}
I have added a lot of code now but I can catch the exception and print it out to see the data I need.
Does it make sense ? Is it possible to get rid of the boilerplate code in myFoo
, myBar
, myQux
? Does Shapeless help here?