From 221b3af888fd65b310ee82b6fd500cd90de3e4fd Mon Sep 17 00:00:00 2001 From: Steve Muir Date: Thu, 13 Feb 2014 11:01:06 -0500 Subject: [PATCH 1/3] SiriusResult should wrap Throwable There's no particular reason why SiriusResult can only wrap RuntimeException as an error, so generalise it to Throwable (analogous to the Try class). --- .../scala/com/comcast/xfinity/sirius/api/SiriusResult.scala | 6 +++--- .../com/comcast/xfinity/sirius/api/SiriusResultTest.scala | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/scala/com/comcast/xfinity/sirius/api/SiriusResult.scala b/src/main/scala/com/comcast/xfinity/sirius/api/SiriusResult.scala index e94e3bad..b4aa64f2 100644 --- a/src/main/scala/com/comcast/xfinity/sirius/api/SiriusResult.scala +++ b/src/main/scala/com/comcast/xfinity/sirius/api/SiriusResult.scala @@ -41,7 +41,7 @@ object SiriusResult { * * @return SiriusResult */ - def error(rte: RuntimeException): SiriusResult = SiriusResult(Left(rte)) + def error(t: Throwable): SiriusResult = SiriusResult(Left(t)) } @@ -53,7 +53,7 @@ object SiriusResult { * methods {@link SiriusResult#some()} and {@link SiriusResult#none()} */ // TODO: hide this within the scope of the companion object? -case class SiriusResult(private val value: Either[RuntimeException, Option[Object]]) { +case class SiriusResult(private val value: Either[Throwable, Option[Object]]) { /** * Does this result contain a value? @@ -73,7 +73,7 @@ case class SiriusResult(private val value: Either[RuntimeException, Option[Objec * @throws IllegalStateException if no such value exists */ def getValue: Object = value match { - case Left(rte) => throw rte + case Left(t) => throw t case Right(Some(v)) => v case Right(None) => throw new IllegalStateException("Result has no value") } diff --git a/src/test/scala/com/comcast/xfinity/sirius/api/SiriusResultTest.scala b/src/test/scala/com/comcast/xfinity/sirius/api/SiriusResultTest.scala index f2af65c2..fd7f59d5 100644 --- a/src/test/scala/com/comcast/xfinity/sirius/api/SiriusResultTest.scala +++ b/src/test/scala/com/comcast/xfinity/sirius/api/SiriusResultTest.scala @@ -59,12 +59,12 @@ class SiriusResultTest extends NiceTest { } it("should rethrow the exception when it has an error") { - val theException = new RuntimeException() + val theThrowable = new Throwable() try { - SiriusResult.error(theException).getValue + SiriusResult.error(theThrowable).getValue assert(false, "Exception should have been thrown") } catch { - case rte: RuntimeException => assert(theException === rte) + case t: Throwable => assert(theThrowable === t) } } } From 986901480ac47413fc4f958198108224c36f9964 Mon Sep 17 00:00:00 2001 From: Steve Muir Date: Thu, 13 Feb 2014 14:54:28 -0500 Subject: [PATCH 2/3] Add exception method to SiriusResult For backwards compatibility purposes it's preferable to not change the signature of the error() method. So let's add an exception() method that allows wrapping of a Throwable in SiriusResult. That way, there is no danger of existing code somehow accidentally getting a Throwable where it expects a RuntimeException. --- .../comcast/xfinity/sirius/api/SiriusResult.scala | 12 ++++++++++-- .../xfinity/sirius/api/SiriusResultTest.scala | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/scala/com/comcast/xfinity/sirius/api/SiriusResult.scala b/src/main/scala/com/comcast/xfinity/sirius/api/SiriusResult.scala index b4aa64f2..19c56985 100644 --- a/src/main/scala/com/comcast/xfinity/sirius/api/SiriusResult.scala +++ b/src/main/scala/com/comcast/xfinity/sirius/api/SiriusResult.scala @@ -41,8 +41,16 @@ object SiriusResult { * * @return SiriusResult */ - def error(t: Throwable): SiriusResult = SiriusResult(Left(t)) - + def error(rte: RuntimeException): SiriusResult = SiriusResult(Left(rte)) + + /** + * Factory method for creating a SiriusResult with an error. + * + * @param rte the RuntimeException to wrap + * + * @return SiriusResult + */ + def exception(t: Throwable): SiriusResult = SiriusResult(Left(t)) } /** diff --git a/src/test/scala/com/comcast/xfinity/sirius/api/SiriusResultTest.scala b/src/test/scala/com/comcast/xfinity/sirius/api/SiriusResultTest.scala index fd7f59d5..a6321272 100644 --- a/src/test/scala/com/comcast/xfinity/sirius/api/SiriusResultTest.scala +++ b/src/test/scala/com/comcast/xfinity/sirius/api/SiriusResultTest.scala @@ -61,7 +61,7 @@ class SiriusResultTest extends NiceTest { it("should rethrow the exception when it has an error") { val theThrowable = new Throwable() try { - SiriusResult.error(theThrowable).getValue + SiriusResult.exception(theThrowable).getValue assert(false, "Exception should have been thrown") } catch { case t: Throwable => assert(theThrowable === t) From ea8caeb9df36ba21bc5865dbc5db3a7fb9ffa700 Mon Sep 17 00:00:00 2001 From: Steve Muir Date: Fri, 14 Feb 2014 16:22:53 -0500 Subject: [PATCH 3/3] Add method to get Throwable Extend SiriusResult with a method to retrieve the associated Throwable without having to catch an exception. --- .../xfinity/sirius/api/SiriusResult.scala | 19 ++++++++++++++++--- .../xfinity/sirius/api/SiriusResultTest.scala | 13 +++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/main/scala/com/comcast/xfinity/sirius/api/SiriusResult.scala b/src/main/scala/com/comcast/xfinity/sirius/api/SiriusResult.scala index 19c56985..5a975687 100644 --- a/src/main/scala/com/comcast/xfinity/sirius/api/SiriusResult.scala +++ b/src/main/scala/com/comcast/xfinity/sirius/api/SiriusResult.scala @@ -41,12 +41,12 @@ object SiriusResult { * * @return SiriusResult */ - def error(rte: RuntimeException): SiriusResult = SiriusResult(Left(rte)) + def error(rte: RuntimeException): SiriusResult = exception(rte) /** - * Factory method for creating a SiriusResult with an error. + * Factory method for creating a SiriusResult with an exception. * - * @param rte the RuntimeException to wrap + * @param t the Throwable to wrap * * @return SiriusResult */ @@ -90,4 +90,17 @@ case class SiriusResult(private val value: Either[Throwable, Option[Object]]) { * @return true if this instance wraps an exception */ def isError: Boolean = value.isLeft + + /** + * Retrieves the exception associated with this result. If an exception + * has not been set an IllegalStateException is thrown. + * + * @return the Throwable wrapped by this instance if it exists + * @throws IllegalStateException if no such Throwable exists + */ + def getException: Throwable = value match { + case Left(t) => t + case _ => throw new IllegalStateException("Result has no exception") + } + } diff --git a/src/test/scala/com/comcast/xfinity/sirius/api/SiriusResultTest.scala b/src/test/scala/com/comcast/xfinity/sirius/api/SiriusResultTest.scala index a6321272..37c37c12 100644 --- a/src/test/scala/com/comcast/xfinity/sirius/api/SiriusResultTest.scala +++ b/src/test/scala/com/comcast/xfinity/sirius/api/SiriusResultTest.scala @@ -87,6 +87,19 @@ class SiriusResultTest extends NiceTest { SiriusResult.error(new RuntimeException()).isError } } + + it("should throw an IllegalStateException when it has no exception") { + intercept[IllegalStateException] { + SiriusResult.none().getException + } + } + + it("should return the exception when it has been set") { + assertResult(true) { + val t = new Throwable() + SiriusResult.exception(t).getException == t + } + } } } }