While using Akka's data-flow DSL, I have twice encountered a need to throw an exception inside future, conditionally. This is how I am doing it:
flow {
// ...
if (someCond)
shiftUnit(throw new SomeException)
else
Future().apply()
// ...
}
Is this the correct way to do it? Or is there a better approach?
The approach seems correct (although my knowledge is a bit rusty), you can even leave out the other branch, the following works for me (Scala 2.10.1):
flow { if (x == 2) shiftUnit(throw new Exception) }
which results in a Future[Unit].
Related
I'm new rather new to Scala so I think this might be a very small problem.
I'm currently trying to change the method chat from using the deprecated WebSocket.async to WebSocket.tryAccept. The application uses the sample chat found at PlayFramework websocket-chat
I'm having trouble creating the complex Future type that the method requires.
This is the old method:
def chat() = WebSocket.async[JsValue] {
request =>
ChatRoom.join("User: 1")
}
New method:
def chat2() = WebSocket.tryAccept[JsValue] {
request =>
try {
// ChatRoom.join returns (iteratee,enumerator)
ChatRoom.join("User: 1").map(e => Right(e))
} catch {
case e: Exception =>
Left(Ok("Failed")) // Error here
}
}
My error message:
found : Left[Result,Nothing]
required: Future[Either[Result,(Iteratee[JsValue, _], Enumerator[JsValue])]]
I have no idea how I am supposed to create such a complex result for such a simple message.
Although ChatRoom.join("User: 1").map(e => Right(e)) doesn't show any errors now, I'm unsure if this is the correct implementation.
I'm not in front of an IDE at the moment, so I can't answer fully, but the return type it's asking for isn't as complex as it seems. An "Either" is a "Left" or a "Right" in the same way that an "Option" is a "Some" or a "None". So what it's asking for is a Future (which Websocket.async should also have required) that contains either a Left[Result] -- the fail-to-connect case, or a Right[(Iteratee, Enumerator)] -- the success case. Assuming that Chatroom.join returns a Future[(Iteratee, Enumerator)], the map operation is simply wrapping that in a "Right". The first thing I'd try is wrapping Left(Ok("Failed")) in a Future and see what happens.
I would like to know the advantage and disadvantage of the following operation
shall i better set the datareader to null than calling the close method. If this is good what are the advantages, else what is the problem in using so?.
You should use the using statement instead:
using (var reader = sqlCommand.ExecuteReader())
{
// do stuff
}
That way, you are sure that the reader is closed (disposed), even if an exception was raised in the "do stuff" block.
For a complete example, see this MSDN page.
Update (regarding your comment):
The using statement is in fact nothing else than a try-finally block to ensure that the reader is disposed (closed) in every case. E.g. the above code is equivalent to this:
SqlDataReader reader = null;
try
{
reader = sqlCommand.ExecuteReader();
}
finally
{
reader.Dispose(); // closes the reader
}
I've just started using Lambda expressions, and really like the shortcut. I also like the fact that I have scope within the lambda of the encompassing method. One thing I am having trouble with is nesting lambdas. Here is what I am trying to do:
public void DoSomeWork()
{
MyContext context = new MyDomainContext();
context.GetDocumentTypeCount(ci.CustomerId, io =>
{
if (io.HasError)
{
// Handle error
}
// Do some work here
// ...
// make DB call to get data
EntityQuery<AppliedGlobalFilter> query =
from a in context.GetAppliedGlobalFiltersQuery()
where a.CustomerId == ci.CustomerId && a.FilterId == 1
select a;
context.Load<AppliedGlobalFilter>(query, lo =>
{
if (lo.HasError)
{
}
**// Do more work in this nested lambda.
// Get compile time error here**
}
}, null);
}, null);
}
The second lambda is where I get the following compile time error:
Cannot convert Lambda expression to type 'System.ServiceModel.DomainService.Client.LoadBehavior' because it is not a delegate type
The compiler is choosing the wrong overload for the Load method even though I am using the same override I did in the previous Lambda.
Is this because I am trying to nest? Or do I have something else wrong?
Thanks,
-Scott
Found the problem as described in my comment above. I'll head back to work now - red face and all....
I realize this is not the answer you want, but I suggest caution about lengthy and/or nested lambdas. They work, but they often make code harder to read / maintain by other developers. I try to limit my lambdas in length to three statements, with no nesting.
I am writing the constructor for my "main" class. The first thing it does is call a method to use commons-cli to parse the command line. If the parseOptions method returns false, an error has occurred, and the constructor should exit.
I tried writing the following code
if (!parseOptions(args)) return
but the compiler complains that I have a "Return statement outside method definition".
Short of calling System.exit(1) or inverting the boolean (and putting all of the rest of my logic inside the if statement, is there any way to return "early" from a constructor?
I suppose I could have the parseOptions method throw an IllegalArgumentException and catch that in my Main object.
Thanks.
Dont try to do a early/premature return, this makes your code harder more complex, since the side effects of the return can be hard to understand. Instead use a exception to signal that something is wrong.
You can use require in the constructor. This doesn't return. But it seems like throwing an exception actually fits his situation better.
As in:
class MyTest(
private var myValue: Int ){
require(myValue > 0) // Connected to constructor
}
defined class MyTest
scala> val x = new MyTest(10)
x: MyTest = MyTest#49ff4282
scala> val y = new MyTest(-10)
java.lang.IllegalArgumentException: requirement failed
at scala.Predef$.require(Predef.scala:133)
is there any way to return "early" from a constructor
No. But in your case it sounds like bad design, anyway.
If the parseOptions method returns false, an error has occurred
In this case the constructor should throw an exception, not return normally.
A constructor should always either complete fully, or abort (throw an exception). Anything else leaves your object "half constructed" and thus impossible to reason about.
If in your case, the object is valid even if parseOptions failed, then you can change the condition and continue:
if (parseOptions(args)) {
// rest of constructor
}
Is there a hook in NUnit to execute code only when assertion fails without catching the exception itself. Basically, it should accept action delegate to be executed when assertion fails and then re-throw exception. Why do I need this?
I need to compare two objects and dump the result on the screen, for easier debugging, when assertion fails.
Something like this works but is a bad hack, The problem is that it eagerly evaluates ProcessCompareError so I have unnecessary overhead, plus it does it no matter if there is an error or not. So, is there overload that will accept the delegate that would be executed when assertion fails?
Assert.That(benefitLimitComparer.Compare(copyBenefitLimit, origBenefitLimit), Is.EqualTo(0),limitError, ProcessCompareError(origBenefitLimit, copyBenefitLimit));
}
}
}
private string ProcessCompareError(BenefitLimit origBenefitLimit, BenefitLimit copyBenefitLimit)
{
Console.WriteLine("Original: ");
ObjectDumper.Write(origBenefitLimit);
Console.WriteLine("Copy");
ObjectDumper.Write(copyBenefitLimit);
return "";
}
I'm not sure how it might be done through a delegate. One alternative is to store the result of the Compare. If the result is false, write out the contents of the objects and then call Assert.Fail()
There is a possibilty to wrap an assert as an Action in a try-catch. In the catch you can handle the additional compare:
public static void ExecuteAssert(Action assert)
{
if (assert == null) return;
try
{
assert();
}
catch (Exception ex)
{
// perform the compare
}
}
As remark: I use a similar method to continue test execution and avoid the entire test to stop, if some non-fatal checks fail. Actually I iterate through a number of actions:
private static void VerifyAll(params Action[] asserts)