I have a wrapper class AwsS3Bucket which when invoked, returns a source Source[ByteString, NotUsed]. In my unit test case, I have mocked this client and do the necessary assertions.
val source = Source.fromIterator(() => List(ByteString("some string")).toIterator)
when(awsS3Bucket.getSource(any[String])).thenReturn(source)
However, now I want to test the error scenario wherein I want the getSource method to throw an exception.
I tried the following code,
val error = new RuntimeException("error in source")
when(awsS3Bucket.getSource(any[String])).thenReturn(error)
but it gives me a compilation issue saying that
Cannot resolve overloaded method thenReturn
Can anyone please let me know the correct method of returning an exception in a Source in akka streams.
You have to use thenThrow(new RuntimeException("error in source")) to stub an Exception.
That said, you may find issues sometimes with checked exceptions as Scala treats all exceptions as runtime, so they aren't declared in the signature, and standard Mockito will validate you're stubbing an exception that can be thrown by the stubbed method.
In mockito-scala that check has been removed to acknowledge the fact that all exceptions behave as runtime in Scala
Related
this is a test program:
object Test {
def main(args: Array[String]): Unit = {
// there is an unhandled exception in here, I expect program can remind me, and I can handled it before running.
myException()
}
def myException: Unit ={
throw new Exception
}
}
In Java, when I called a method with unhandling exception, the program will occur error, and tell you add throws declaration or surround with try/catch.
How to know the program have unhandled exceptions before running in Scala?
Scala has a somewhat different philosophy with regards to Exceptions.
The rule of thumb is to not use them unless for something truly exceptional and, thus "let it fail". The reason invoked behind this rule is that, in FP terms, exceptions break referential transparency.
The good practice is to use Either or Option to handle/wrap "errors" rather than throwing exceptions. (the link provided by #Tawkir seems a good read)
Unfortunately this does not help when interfacing with Java code which often uses Exceptions for program control flow, and the compiler will not help you there. A practical way around this is to wrap Exception throwing code with a Try and then call recover or recoverWith to handle these exceptions and, say, wrap them in another structure.
Please note that you can mark a scala method with an #throws annotation to specify the Exception(s) that this method throws, but this should really be used when writing scala code meant to be used by a Java caller expecting an Exception to be thrown.
There's no distinction between checked and unchecked exceptions in the JVM. This is only enforced in the Java compiler, based on whether the class extends RuntimeException or not. Scala compiler doesn't check it, so, there is no way to know, does program have unhandled unchecked exceptions, or not.
This is a rather general question, but hopefully a reasonable one. When is ExecutionContext#reportFailure(Throwable) called?
It doesn't seem to be called in the Scala standard library. I suppose I perhaps should call it in some circumstances? What are these?
This method reports exceptions that cannot be reported otherwise.
It is called when an exception happens during the execution of a callback that has no other way of reporting failure. In particular, calls to Future.onComplete (e.g. via Future.foreach) return Unit and may be executed on any thread, so they have no way of reporting failure back to their callers. When an exception is thrown within onComplete, it is sent to this method.
It is called a couple of times deep within the implementation for Promise in the standard library. See the source.
try onComplete(value) catch { case NonFatal(e) => executor reportFailure e }
An ExecutionContext can implement reportFailure to execute arbitrary code when a future/promise fails. The only thing in the standard library that implements this method is ExecutionContextImpl, which is not in the public API, but found here. This class accepts a reporter: Throwable => Unit function. The default ExecutionContext.Implicits.global uses ExecutionContext.defaultReporter, which simply prints the stack trace to System.err.
If you wanted to customize the behavior, you could need to define your own ExecutionContext. It's difficult to imagine a scenario where you'd want to produce some other side-effect other than logging the stack trace, or some other kind of logging.
I'm using the constructor Future.failed to create a failed future, but the failed future still throws the exception when I think it should not.
The method session.loadAll does throw an exception.
I'm also using the Play Framework
It even happens using a try-catch block
I think that Future.failed is not throwing the exception. It looks like it is, because the stack trace is generated at the place where the exception is created.
So, if you use a method like Await.result, or another method that assumes that a future is successful, you will see the exception re-thrown, but the stack trace will make it look as if it was thrown in Future.failed.
First, I'm not quite sure why you're using a future here because these don't look like asynchronous calls.
To answer your question, however, I'm not entirely sure what is going on here, but it looks like you need to be handling the exception. The consumer of the future should use either Future.onComplete and pattern match a Failure type, or Future.onFailure and pattern match on Throwable types.
Scala docs on Future: http://docs.scala-lang.org/overviews/core/futures.html
If a Scala future fails, and there is no continuation that "observes" that failure (or the only continuations use map/flatMap and don't run in case of failure), then errors go undetected. I would like such errors to be at least logged, so I can find bugs.
I use the term "observed error" because in .Net Tasks there is the chance to catch "unobserved task exceptions", when the Task object is collected by the GC. Similarly, with synchronous methods, uncaught exceptions that terminate the thread can be logged.
In Scala futures, to 'observe' a failure would mean that some continuation or other code reads the Exception stored in the future value before that future is disposed. I'm aware that finalization is not deterministic or reliable, and presumably that's why it's not used to catch unhandled errors, although .Net does succeed in doing this.
Is there a way to achieve this in Scala? If not, how should I organize my code to prevent unhandled error bugs?
Today I have andThen checkResult appended to various futures. But it's hard to know when to use this and when not to: if a library method returns a Future, it shouldn't checkResult and log errors itself, because the library user may handle the failure, so the responsibility falls onto the user. As I edit code I sometimes need to add checks and sometimes to remove them, and such manual management is surely wrong.
I have concluded there is no way to generically notice unhandled errors in Scala futures.
You can just use Future.recover in the function that returns the Future.
So for instance, you could just "log" the error and rethrow the original exception, in the simplest case:
def libraryFunction(): Future[Int] = {
val f = ...
f.recover {
case NonFatal(t) =>
println("Error : " + t)
throw t
}
}
Note the use of NonFatal to match all the exception types it is sensible to catch.
That recover block could equally return an alternative result if you wish.
Can someone tell me what "Fragment evaluation error" means, or where I might look for solutions? I sometimes (but not always) get lots of these errors (without changing my code):
[error] ! Fragment evaluation error
[error] ThrowableException: Could not initialize class code.model.Post$ (FutureTask.java:138)
[error] code.model.PostSpec$$anonfun$1$$anonfun$apply$1.apply$mcZ$sp(PostSpec.scala:68)
[error] code.model.PostSpec$$anonfun$1$$anonfun$apply$1.apply(PostSpec.scala:51)
[error] code.model.PostSpec$$anonfun$1$$anonfun$apply$1.apply(PostSpec.scala:51)
Line 68 of PostSpec is the first line in the (specs2) test that references the Post model companion object:
val test4 = Post.fixJValue(toextract4).extract[Selection]
I'm using Scala 2.9.0-1.
Also: I have no idea whether it matters, but Post is a net.liftweb.mongodb.record.MongoRecord class companion object:
object Post extends Post with MongoMetaRecord[Post] { ... }
In a specs2 specification, Fragments are pieces of the specification. A Fragment can be a Text, an Example, a Step.
Some fragments, like Example and Step are meant to be executed and are supposed to catch Exceptions so that they can be marked as failures. But they won't catch Errors (except AssertionErrors). So if an Example throws an OutOfMemoryError, this will be reported as a Fragment evaluation error.
Other fragments, like Text fragments are not supposed to throw exceptions when being evaluated. If they do, you will get the same Fragment evaluation error message.
Without seeing the full specification it's hard for me to say what's happening there but I suspect that you had a non-Exception type thrown in the body of an Example. But I have more questions than answers for now:
where is test4 declared? Inside the specification body? Inside a Context case class?
since errors happen intermittently, are you sure you always have a proper mongodb context? Maybe your specification examples are being executed concurrently on the same mongo db instance?