Skip to content

Instantly share code, notes, and snippets.

@randomstatistic
Created July 13, 2018 18:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save randomstatistic/e661c6b87144efef62d2a61513f2e6bc to your computer and use it in GitHub Desktop.
Save randomstatistic/e661c6b87144efef62d2a61513f2e6bc to your computer and use it in GitHub Desktop.
Scala try-with-resources equivelent
import java.io.Closable
import scala.util.control.NonFatal
import scala.util.{ Success, Try }
// This should really be scala-standard-lib.
object TryWithResources {
def withClose[T <: Closeable, V](closable: T)(f: T => V): V = {
(Try(f(closable)), Try(closable.close())) match {
case (Success(v), Success(_)) => v
case (a, b) => throw preferFirstException(a, b).get
}
}
// Any subsequent exceptions are appended (as "suppressed") to the first exception.
// Having been altered as necessary, the first exception is then given back as the return value.
// "Fatal" exceptions are immediately rethrown, however.
def preferFirstException(exceptions: Try[_]*): Option[Throwable] = {
val (failures, fatal) = exceptions.filter(_.isFailure).map(_.failed.get).partition(NonFatal(_))
fatal.headOption.foreach(throw _)
if (failures.size <= 1) {
failures.headOption
} else {
Some(failures.tail.fold(failures.head) { case (a, b) =>
a.addSuppressed(b)
a
})
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment