From 74e3b4dc8b85b0f861ce9a87e8765654a3ac40f8 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Mon, 20 Aug 2012 11:29:24 -0400 Subject: Unify scala.util.control.Exception with scala.util.Try --- src/library/scala/util/control/Exception.scala | 43 ++++++++++---------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/src/library/scala/util/control/Exception.scala b/src/library/scala/util/control/Exception.scala index 2ee053c92b..4a5209ecab 100644 --- a/src/library/scala/util/control/Exception.scala +++ b/src/library/scala/util/control/Exception.scala @@ -6,7 +6,8 @@ ** |/ ** \* */ -package scala.util.control +package scala.util +package control import collection.immutable.List import reflect.{ ClassTag, classTag } @@ -25,6 +26,10 @@ import language.implicitConversions * val x2 = catching(classOf[MalformedURLException], classOf[NullPointerException]) either new URL(s) * }}} * + * This class differs from `scala.util.Try` in that it focuses on composing exception handlers rather than + * composing behavior. All behavior should be composed first and fed to a `Catch` object using one of the + * `opt` or `either` methods. + * * @author Paul Phillips */ @@ -118,6 +123,11 @@ object Exception { */ def either[U >: T](body: => U): Either[Throwable, U] = toEither(Right(body)) + /** Apply this catch logic to the supplied body, mapping the result + * into Try[T] - Failure if an exception was caught, Success(T) otherwise. + */ + def withTry[U >: T](body: => U): scala.util.Try[U] = toTry(Success(body)) + /** Create a `Catch` object with the same `isDefinedAt` logic as this one, * but with the supplied `apply` method replacing the current one. */ def withApply[U](f: Throwable => U): Catch[U] = { @@ -131,35 +141,11 @@ object Exception { /** Convenience methods. */ def toOption: Catch[Option[T]] = withApply(_ => None) def toEither: Catch[Either[Throwable, T]] = withApply(Left(_)) - } - - /** A container class for Try logic */ - class Try[+T] private[Exception](body: => T, val catcher: Catch[T]) { - /** Execute "body" using catch/finally logic "catcher" */ - def apply(): T = catcher(body) - def apply[U >: T](other: => U): U = catcher(other) - - /** As apply, but map caught exceptions to `None` and success to `Some(T)`. */ - def opt(): Option[T] = catcher opt body - def opt[U >: T](other: => U): Option[U] = catcher opt other - - /** As apply, but map caught exceptions to `Left(ex)` and success to Right(x) */ - def either(): Either[Throwable, T] = catcher either body - def either[U >: T](other: => U): Either[Throwable, U] = catcher either other - - /** Create a `Try` object with the supplied body replacing the current body. */ - def tryInstead[U >: T](other: => U) = new Try(other, catcher) - - /** Create a `Try` object with the supplied logic appended to the existing Catch logic. */ - def or[U >: T](pf: Catcher[U]) = new Try(body, catcher or pf) - - /** Create a `Try`object with the supplied code appended to the existing `Finally`. */ - def andFinally(fin: => Unit) = new Try(body, catcher andFinally fin) - - override def toString() = List("Try()", catcher.toString) mkString " " + def toTry: Catch[scala.util.Try[T]] = withApply(x => Failure(x)) } final val nothingCatcher: Catcher[Nothing] = mkThrowableCatcher(_ => false, throw _) + final def nonFatalCatcher[T]: Catcher[T] = mkThrowableCatcher({ case NonFatal(_) => false; case _ => true }, throw _) final def allCatcher[T]: Catcher[T] = mkThrowableCatcher(_ => true, throw _) /** The empty `Catch` object. */ @@ -168,6 +154,9 @@ object Exception { /** A `Catch` object which catches everything. */ final def allCatch[T]: Catch[T] = new Catch(allCatcher[T]) withDesc "" + /** A `Catch` object witch catches non-fatal exceptions. */ + final def nonFatalCatch[T]: Catch[T] = new Catch(nonFatalCatcher[T]) withDesc "" + /** Creates a `Catch` object which will catch any of the supplied exceptions. * Since the returned `Catch` object has no specific logic defined and will simply * rethrow the exceptions it catches, you will typically want to call `opt` or -- cgit v1.2.3