Reputation: 8412
My application reads some configuration values from a file. If there are any errors in the process, I would like to set default values for those configuration parameters. What I am doing is:
val (param1, param2) = {
try{
val props = new java.util.Properties
props.load(getClass.getResource("/myapp.properties").openStream)
(
props.getProperty("param1", "default1"),
props.getProperty("param2", "default2")
)
}
catch{
case _ => ("default1", "default2")
}
}
I know that what I am doing in the catch block won't work as expected if there is an exception. Is there a way to fix it? I'm using Scala 2.9
Upvotes: 2
Views: 1552
Reputation: 167921
This will work, but it opens up the possibility of a run-time error since
val (a,b) = whatever
may be called as long as whatever
is a supertype of Tuple2
--in particular, it could be AnyRef
or Any
, which is indeed what the try/catch return value will be widened to if you have sufficiently mismatching types. You can make sure it's the right type by adding a type ascription:
val (a,b): (A, B) = whatever
and then the type checker will complain if the right-hand-side is not the correct type all the way through the try/catch.
For example:
val (a,b): (String, String) = try {
("perch", if (scala.util.Random.nextBoolean) throw new Exception else "halibut")
} catch {
case e: Exception => ("salmon", "herring")
}
If you tried to add , "cod"
after "herring"
you'd get a compile-time error. This assignment, if entered repeatedly, will give you a=perch and b=halibut half the time and a=salmon and b=herring the other half.
Addendum: in 2.9 (or below, I presume, though I haven't checked), you have to put the type ascription on the try/catch statement like so:
val (a,b) = (try {
("perch", if (scala.util.Random.nextBoolean) throw new Exception else "halibut")
} catch {
case e: Exception => ("salmon", "herring")
}): (String, String)
to get the type-checking of the catch.
Upvotes: 4