I'm getting a code analysis warning on some of my unit tests:
WidgetManagerTests.cs (40): CA2000 :
Microsoft.Reliability : In method
'WidgetManagerTests.TestInitialize()',
call System.IDisposable.Dispose on
object 'new
ContainerControlledLifetimeManager()'
before all references to it are out of
scope.
I'm using Unity and Moq, this is the offending line:
var loggingServiceMock = new Mock<ILoggingService>();
this.unityContainer.RegisterInstance<ILoggingService>(loggingServiceMock.Object, new ContainerControlledLifetimeManager());
The CA2000 implementation is very sensitive to cases where an exception might be thrown before a disposable instance is "handed off" to another method. In this case, even though the container will eventually take care of cleaning up the lifetime manager if no exceptions occur during registration, it's possible an exception to occur either before the RegisterInstance call or within the call but before the container add the lifetime manager to its own internal state.
To address this possibility, you could use code like the following (although I probably wouldn't bother with this myself unless the disposition did something significant):
var loggingServiceMock = new Mock<ILoggingService>();
var lifetimeManager = new ContainerControlledLifetimeManager();
try
{
this.unityContainer.RegisterInstance<ILoggingService>(loggingServiceMock.Object, lifetimeManager);
}
catch
{
lifetimeManager.Dispose();
throw;
}
Related
Below is a minimal example of the problem I am currently encountering:
using System.Net.WebSockets;
using AutoFixture;
using AutoFixture.AutoMoq;
using FluentAssertions;
using Xunit;
...
[Fact]
public void Test1()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization() { ConfigureMembers = true });
var sut = fixture.Create<WebSocket>();
sut.Should().NotBeNull();
}
[Fact]
public void Test2()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization() { ConfigureMembers = true });
var sut = new Mock<WebSocket>().Object;
fixture.Inject(sut);
sut.Should().NotBeNull();
}
...
When I run the first test, I get the following exception:
AutoFixture.ObjectCreationExceptionWithPath : AutoFixture was unable to create an instance from Moq.Mock`1[System.IO.Stream] because creation unexpectedly failed with exception. Please refer to the inner exception to investigate the root cause of the failure.
Inner exception messages:
System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
The second test succeeds.
I would like to be able to create an instance of a class using AutoFixture which takes a WebSocket as a constructor parameter, without the need to inject a mock object first (ultimately, so that I can use an AutoMoqData attribute, and get rid of some boilerplate). Have I got any misusage or misunderstanding going on here, or would this be better placed as a GitHub issue? In the interim, is there anything I can do to work around this issue?
You observe this issue because of the AutoFixture's factory discovery strategy. When you try to create an object of an abstract type, AutoFixture still inspects the type to find a static factory method to activate the object. In your particular case, the WebSocket type contains such methods, so some of them is used. It looks like it doesn't work well with auto-generated input values, so fails with an exception.
You can customize AutoFixture, to always mock the WebSocket type:
fixture.Register((Mock<WebSocket> m) => m.Object);
Just tested with the latest versions of products (AutoFixture 4.5.0, Moq 4.10.0) and it works like a charm.
I want some kind of mechanism to have more information about a caught exception. (Specifically exceptions I throw myself to abort transactions) I've looked around and pretty much the only thing I could find was "Use the info log". This to me does not seem like a good idea. For one it is cumbersome to access and find the last message. And it is limited in size so at some point the new messages won't even show up.
So my idea is the following: Create a class NuException and pass an instance of that through all methods store an instance in the class where the work methods are located. When I need to throw an exception I call a method on it similar to Global::error() but this one takes an identifier and a message.
Once I reach my catch block I can access those from my object the class that contains the work methods similarly to how CLRExceptions work.
class NuException
{
"public" str identifier;
"public" str message;
public Exception error(str _id, str _msg)
{
//set fields
return Exception::Error;
}
}
class Worker
{
"public" NuException exception;
void foo()
{
throw this.exception.error("Foo", "Record Foo already exists");
}
void bar()
{
this.foo();
}
}
void Job()
{
Worker w = new Worker();
try
{
w.bar(ex);
}
catch (Exception::Error)
{
info(w.exception().message());
}
}
It works but isn't there a better way? Surely someone must have come up with a solution to work around this shortcoming in AX?
Short answer: yes.
While your "brilliant" scheme "works", it gets boring pretty fast, as you now must transport your NuException object deep down 20 level from the listener (job) to the thrower (foo). Your bar method and other middle men has no interest or knowledge about your exception scheme but must pass it on anyway.
This is no longer the case after the update.
There are several ways to go.
Use an observer pattern like the Event broker or in AX 2012 and newer use delegates.
Stick to the infolog system and you use an InfoAction class to peggy bag your information to be used later. It can be used to display a stack trace or other interesting information.
Use a dedicated table for logging.
The third way may seem impractical, as any errors will undo the insert in the log. This is the default behavior but can be circumvented.
MyLogTable log;
Connection con = new UserConnection();
con.ttsBegin();
log.setConnection(con);
... // Set your fields
log.insert();
con.ttsCommit();
Your way to go depends on circumstances you do not mention.
I am working on JavaFX application and I want to know if there is a way to handle exceptions in one place.
I am doing inserts into database. And when an insert fails, I get an SQLException.
So, is it possible to handle all SQLExceptions (for all inserts) in one place?
I'm aware of:
Thread.setDefaultUncaughtExceptionHandler(...);
But this is probably not the way to go?
It is bad practice to call any code that executes your SQL query (or any other business logic that may take long to execute) directly in the JavaFX application Thread. (I've observed that under Windows JavaFX applications crash without even printing a stacktrace when an uncaught exeption is thrown in the application thread.)
I would suggest to call your SQL-related code using an javafx.concurrent.Task.
Using the setOnFailed() method you can have code invoked whenever an Execption is thrown. There you can look for the type of exception and call any method that handles your SQLException.
Task<SOME_TYPE> mySqlTask = new Task<>() {
#Override
protected SOME_TYPE call() throws Exception {
... // do sql stuff
return mySqlResult; // or null if not needed
}
};
mySqlTask.setOnFailed(event -> {
Throwable exception = mySqlTask.getException();
if (exception instanceof SQLException) {
// call code that handles the sql exception
}
});
// start the task in a separate thread (or better use an Executor)
new Thread(mySqlTask).start();
By the way, I don't think that using Thread.setDefaultUncaughtExceptionHandler(...); is the way to go neither.
I am very new to Workflow Foundation development, and am worried that I am opening serious holes in our business process handling by not properly handling application / database exceptions in custom activities.
I would appreciate some steps that I could take to add this resiliency to my custom activities so that I can easily use the designer and other tools to ensure that, as far as I can, I do not create custom activities that are brittle and likely to cause workflow cleanup issues.
Here are some options, at different execution stages, that are available for you to use to handle exceptions.
First option (at activity/workflow execution time):
First of all, on custom activities, you should always try to treat exceptions inside it's execution. Some activities might not work but the overall workflow can continue and, in such cases, log the error to persistence and even show the user that something didn't work as expected but the thing will continue are good options.
That being said there'll always be cases where an activity have to (and even should) thrown exceptions and those should be treated at workflow level. Something like: if this exception occurs on this activity, do this, otherwise, do that.
Lets imagine you've a custom activity which persists something to DB:
public sealed PersistIntegerToDb : CodeActivity
{
public InArgument<int> ValueToPersist { get; set; }
protected override void Execute(CodeActivityMetadata metadata)
{
try
{
// persist
}
catch(SqlException exception)
{
// re throws the SqlException
throw new SqlException("'ValueToPersist' wasn't persisted.", exception);
}
}
}
Then, in your code or through designer you've available TryCatch activity to catch that error and treat it the way you want:
var workflow = new TryCatch
{
Try = new PersistIntegerToDb
{
ValueToPersist = 10
},
Catches =
{
new Catch<SqlException>
{
Action = new ActivityAction<SqlException>
{
Handler = new WriteLine
{
Text = "An error occurred and the value wasn't saved! Anyway workflow will continue..."
}
}
}
}
}
Or you can terminate it using TerminateWorkflow.
Second option (at design time):
Ok, but you can argue that client doesn't know that he have to handle those cases. In that case, and this is an usability option you might consider, instead of making available PersistIntegerToDb on the designer, you can provide an activity already surrounded by exceptions catches to handle, through IActivityTemplateFactory:
public sealed PersistIntegerToDbFactory : IActivityTemplateFactory
{
public Activity Create(DependencyObject target)
{
return new TryCatch
{
Try = new PersistIntegerToDb
{
ValueToPersist = 10
},
Catches =
{
new Catch<SqlException>
{
}
}
};
}
}
Now you just add PersistIntegerToDbFactoryas if it were a regular activity:
new ToolboxItemWrapper(typeof(PersistIntegerToDbFactory), null, "Persist Integer");
Third option (at validation time):
Never forget to validate workflow before execution!
var validationResults =
ActivityValidationServices.Validate(workflow);
foreach(var error in validationResults.Errors)
{
Console.WriteLine(string.Format(
"Validation error '{0}', generated on activity '{1}' in the property named {2}",
error.Message,
error.Source.DisplayName,
error.PropertyName));
}
Fourth option (at application execution time):
You can handle all not treated exception that might happen during execution, using OnUnhandledException event:
var wfApp = new WorkflowApplication(activity);
wfApp.OnUnhandledException +=
delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
{
if (e.UnhandledException is SqlException)
{
Console.WriteLine("Some data wasn't properly persited.");
}
else
{
Console.WriteLine("Unknown error: " + e.UnhandledException.GetType());
Console.WriteLine("With message: " + e.UnhandledException.Message);
}
Console.WriteLine("Ok, workflow will be abort");
return UnhandledExceptionAction.Abort;
};
Note that, at this stage, you can only Abort, Cancel and Terminate the workflow and that's the reason why you should 1) avoid throwing exceptions or 2) treat exceptions inside your workflow. OnUnhandledException is your last chance to end the workflow execution gracefully and should always be treated even if for logging purposes. Something like DivideByZeroExceptions can occur and are almost impossible to predict and catch at validation time, for example.
As far as custom activities goes you should treat them as any other piece of code. Handle the errors you can and let you can't handle the rest bubble up.
At the workflow level you can use the TryCatch activity and workflow persistence to deal with errors. Specially persistence is something people overlook often. Add Persist activities at appropriate steps in your workflow and set the workflow to abort on unhandled errors. Now you can go back in and reload the last good workflow state and retry the actions that cause an unhandled exception. A great way of recovering from failures with resources like databases that might be unavailable for some reason and then come back.
Im trying to connect a Flash client to BlazeDS. There has been some success with this from others using the vanilla BlazeDS setup. However I'm using the new Spring BlazeDS Integration from springsource and running aground.
The flash client actually seems to be working in that I can see the correct data in the body of the returned object, but for some reason unknown it fails casting as an IMessage. It fails in PollingChannel.as on this line with the subject line error
var messageList:Array = msg.body as Array;
for each (var message:IMessage in messageList) <--
On application load I register a whole bunch of classes like so
registerClassAlias( "flex.messaging.messages.RemotingMessage", RemotingMessage );
registerClassAlias("mx.messaging.messages.IMessage", IMessage);
etc..
my code is basically
var channelSet:mx.messaging.ChannelSet = new mx.messaging.ChannelSet();
var channel:mx.messaging.channels.AMFChannel = new AMFChannel("my-amf", "http://localhost:8400/SpringA/messagebroker/amf");
channelSet.addChannel(channel);
var consumer:mx.messaging.Consumer = new Consumer();
consumer.channelSet = channelSet;
consumer.destination = "simple-feed";
consumer.subscribe();
consumer.addEventListener(MessageEvent.MESSAGE, test);
private function test(event:IMessage)
{
trace("msg..");
// breakpoint never makes it here
}
I have a flex client which works 100% with same destination/channel.
The error in the title means that you, for some reason, got an object that is not implementing or extending the IMessage interface, therefore the loop can not cast it in this part:
for each (var message:IMessage in messageList){
Either you should somehow make sure that you don't add anything that is not extending or implementing IMessage, or check if the variable IS actually ext./imp. it. Also - if you want to do that, you will have to change the for each like this:
for each (var obj in messageList){
if (obj is IMessage){
var message:IMessage = obj as IMessage;
// DO STUFF HERE
}
}
Add this Object mapping:
registerClassAlias("flex.messaging.io.ObjectProxy", ObjectProxy);
If on your Java VO objects you have overridden the hashcode() method, this situation could happen.
Remove the hashcode() override (if you are able to).
See my blog for the backstory on how I discovered this. http://squaredi.blogspot.com/2013/12/remoting-landmine-without-stack-trace.html
I had the same error when trying to send an actionscript object to the backend. My problem was that my c# equivalent object was missing an public parameterless constructor.