summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/util/control/Exception.scala43
-rw-r--r--test/files/run/try-catch-unify.check3
-rw-r--r--test/files/run/try-catch-unify.scala15
3 files changed, 34 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(<body>)", 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 "<everything>"
+ /** A `Catch` object witch catches non-fatal exceptions. */
+ final def nonFatalCatch[T]: Catch[T] = new Catch(nonFatalCatcher[T]) withDesc "<non-fatal>"
+
/** 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
diff --git a/test/files/run/try-catch-unify.check b/test/files/run/try-catch-unify.check
new file mode 100644
index 0000000000..b1de2bfa74
--- /dev/null
+++ b/test/files/run/try-catch-unify.check
@@ -0,0 +1,3 @@
+Failure(java.lang.NumberFormatException: For input string: "Hi")
+Success(5.0)
+O NOES
diff --git a/test/files/run/try-catch-unify.scala b/test/files/run/try-catch-unify.scala
new file mode 100644
index 0000000000..0d819ab957
--- /dev/null
+++ b/test/files/run/try-catch-unify.scala
@@ -0,0 +1,15 @@
+import util._
+
+import control.Exception._
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ println(catching(classOf[NumberFormatException]) withTry ("Hi".toDouble))
+ println(catching(classOf[NumberFormatException]) withTry ("5".toDouble))
+ try {
+ catching(classOf[NumberFormatException]) withTry (sys.error("O NOES"))
+ } catch {
+ case t => println(t.getMessage)
+ }
+ }
+}