Scala Gotcha: Ignoring Return Value of Using
Scala's Try
is well-known utility to handle exceptions in a functional manner. A related util is scala.util.Using
which wraps a resource that needs closing (like a file or network connection) and automatically handles it for the user:
Using(openStream("foo.txt")) { stream =>
stream.foreach(handleStreamElement)
// stream gets automatically closed here
}
Unfortunately, there is a bug hidden in above code: What happens if handleStreamElement
throws an exception?
As Using.apply(...)
returns a Try[R]
, the developer has to check the return value fo see if the operation succeeded or failed. If the return value is unused - as above - errors are silently discarded.
If we don't care about the return value, we should at least add a .get
at the end of the code block. On a Failure
, .get
will Failure.get
will throw the failure's exception:
Using(...) { resource =>
// Use resource
}.get // Unwrap Try[R]; will throw an exception on Failure
Another option is using scala.util.Using.resource(...)
which returns a R
instead of Try[R]
and rethrows exceptions:
Using.resource(...) { r =>
// Use r
}