I wrote an application that loops through a set of records and prints two things.
One is a report from SSRS wich works correctly.
The other is a drawing that uses a COM object to print. The COM object randomly fails and causes the program to quit.
Is there a way to stop it from killing the entire program when the COM Object fails? I have tried catch every exception at every level and it still does not work.
Do you have the code of COM object that you are calling. If you have code then check whether there any exit command on failure.
Are you using the COM object from multiple threads? You should only access the COM object from a single thread with a message pump. In my experience this can cause weird instability which cannot be trapped via a try-catch.
It sounds like the issue maybe with the com object itself and not your code. If this is the case then if the com object does not throw an error then you will not be able to catch one.
Kind Regards
Tony Smith-Brewster
Related
My main program is an ASP.Net Core Web API that has a third party library in a hosted service. The third party library is initializing fine but then it throws some errors sometime throughout its lifecycle.
It supplies a way of hooking into the object via an event and will let me know what the error is so that I can handle it but it still throws in the third party library..
Since I am handling the event myself, I want to completely ignore these errors that are occurring in this library. Is there anyway that I can do that?
I have already tried to add a global exception handler and the strange thing is, this exception handler never gets hit. The only way I can get the exception is to set my exception settings to break when CLR exceptions happen like in the picture above
This does not crash my program. For some reason, the program just hangs. When I turn off CLR exceptions in the "Break when thrown" window, then the program runs just fine. It is almost like visual studio is doing something special to handle these types of exceptions that a console version cannot do
The only way that I can seem to get a console version of this running, is attach a visual studio debugger to the process and when the exception is hit, press the green play button "Continue" in visual studio. Otherwise the application just seems to hang on the exception being thrown by the third party library.
The application will run fine as long as visual studio is attached and the CLR break exceptions are not checked
Does anyone know how to make sure that these types of exceptions do not hang the program when released?
Additional Info:
The third party library is a .NET Framework 4 library
The Asp.Net project is targetting "net5.0-windows"
The 3rd party class is probably using multi-threading
if it helps, this is how I am creating the third party class
Handling NullReferenceException in release code(Official advice)
It's usually better to avoid a NullReferenceException than to handle it after it occurs. Handling an exception can make your code harder to maintain and understand, and can sometimes introduce other bugs. A NullReferenceException is often a non-recoverable error. In these cases, letting the exception stop the app might be the best alternative.
However, there are many situations where handling the error can be useful:
1.Your app can ignore objects that are null. For example, if your app retrieves and processes records in a database, you might be able to ignore some number of bad records that result in null objects. Recording the bad data in a log file or in the application UI might be all you have to do.
2.You can recover from the exception. For example, a call to a web service that returns a reference type might return null if the connection is lost or the connection times out. You can attempt to reestablish the connection and try the call again.
3.You can restore the state of your app to a valid state. For example, you might be performing a multi-step task that requires you to save information to a data store before you call a method that throws a NullReferenceException. If the uninitialized object would corrupt the data record, you can remove the previous data before you close the app.
4.You want to report the exception. For example, if the error was caused by a mistake from the user of your app, you can generate a message to help them supply the correct information. You can also log information about the error to help you fix the problem. Some frameworks, like ASP.NET, have a high-level exception handler that captures all errors to that the app never crashes; in that case, logging the exception might be the only way you can know that it occurs.
So after days of research I've finally found an event to hook into to give you error messages from ANY source no matter how many level deep you go in threads.
AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
Hooking into this event it will allow you to see errors from every library and every thread. Simply place the above into you program.cs (or whatever startup file you have) and magically you will be flooded with all of the unknown errors from all of the 3rd party libraries you thought were once flawless.
private static void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
{
Console.WriteLine(e.Exception.Message, e.Exception.StackTrace);
}
I've done so with the following method and low and behold. The third party library was trying to reference another project in an unsafe way and throwing an error. Since I didn't need this other project reference the built exe did not have a reference to this assembly because I had no direct reference to it in the project (darn smarty pants who need to optimize everything). I was able to run correctly because in my visual studio solution, I had a reference to this other project. So the third party library would pick up on it as soon as visual studio connected with the debugger through some sort of dark magic.
Anyways, I made a throw away object that used the project that was required and the issue was solved.
I really hope that this helps someone else and saves them the days it took me to find this.
I have a function in vb.net that is shared. At one point it throws an error that says an 'open datareader already exists'. But this function is called from several different places in the program. How can I find out which part of the program called the function when it errors out?
You go to the Debug menu, show the Exceptions window, put a tick next to CLR exceptions and then run your program until it errors. As soon as the exception is raised VS will break, you will be able to see the call stack, and find out where the code was before. Note that this causes VS to stop on every exception, handled or not; it can become tedious to get to where you want to be - untick the "always break when this type of exception is thrown" in the exception helper if you just keep getting irrelevant exceptions breaking before this error you're trying to chase
It sounds like you're perhaps not creating/disposing of your DB access resources properly, especially if this is a static/shared context. Are you trying to reuse one DB connection? It wouldn't hurt to post the code of the faulting module
I was using an application and it was working perfect. After some months of not using it, I tried to run it and it doesn't work. It shows a message box saying that it cannot instance a COM object.
Do any know how to track errors in COM objects?
You can use ProcessMonitor and try to find the registry key that may be incorrect.
The other option is to use http://www.moduleanalyzer.com, it intercepts CoCreateInstance showing all created COM objects and the return values.
Run Depends tool on COM object DLL to verify it has all the necessary dlls, re-register the COM dll/exe.
Any HRESULTS from debugging/logs? Any changes in apartment models?
You cannot change the apartment type once you've set one. So if the object cannot use one of the models and you try to CoCreate it, it will fail. That's why you never call CoInit from inside DLL main thread.
Have been searching for a solution to this problem for days with no luck so I decided to post here and hope someone can help me. What makes it even harder is that I can't replicate this problem on my computer very consistently. Sometimes I will get the error but most of the time I won't.
Basically what is happening is I am creating an IE object which my program then controls for a long period of time. What is happening is, if a user exits the program it calls oIE.Quit() then closes the program. This should close internet explorer and all processes associated with it.
But, the iexplorer process doesn't end up closing. Then when the user tries to run the program again we get this error "System.Runtime.InteropServices.COMException (0x80004005): Creating an instance of the COM component with CLSID {0002DF01-0000-0000-C000-000000000046} from the IClassFactory failed due to the following error: 80004005.".
To fix this we simply close the any iexplorer.exe processes that are open and it will let us create our ie object again. This happens also if the program crashes and they try to restart it.
I am not sure what is causing this or if I am missing something that has to do with com objects. But I am simply stuck.
Here is some code although plugging in this code likely won't reproduce any errors:
'create ie object
oIE = New SHDocVw.InternetExplorer
oIE.Navigate("http://www.google.com")
oIE.Visible = False
oIE.Silent = True
'kill ie object
oIE.Quit()
The exception you get is hopeless, that's E_FAIL, "Unspecified error". There isn't any obvious reason why this would fail, starting another instance of IE when your program starts back up shouldn't be a problem. Well, short from those ghost instances of IE that keep running forever. I would guess that you got this exception for the same reason that IE didn't quit when you called Quit() the last time.
Do consider the kind of mishap you'll create when your program aborts and doesn't get around to cleanly shutting down IE. Using Environment.Exit() would be quite unhealthy for example. Or any other kind of nasty kaboom that doesn't let the finalizer thread run at termination. Maybe that has already happened many times before, now IE just refuses to create any more instances? How many instances do you have to kill when you need to get it going again?
The much better mousetrap here is to run IE in-process in your own program rather than out-of-process with SHDocVw. So that when your program terminates, it takes IE with it. It is also much more efficient, there's a lot of overhead involved in making out-of-process COM server calls.
You do this by using WebBrowser in your program.
I have some VB.NET code that creates a TransactionScope instance:
LoggingUtility.LogDebug("UpdateCallTable", "SatComCallDataImporter", "About to associate call data with contracts")
Using ts = New TransactionScope()
LoggingUtility.LogDebug("UpdateCallTable", "SatComCallDataImporter", "Getting all unimported SatCom calls")
My application is throwing an exception on the call to the creation of a new TransactionScope, with "Object reference not set to an instance of an object.". The exception isn't thrown on my development machine or my test machine; only on the customers production machine, and I have no idea why. I've placed debug lines immediately before and after this line so I'm positive it is this line causing the problem.
A have used TransactionScopes throughout the application and this is the only place throwing the exception on the client machine.
"About to associate call data with contracts" gets written to the log and the next log entry is the "Object reference not set to an instance of an object".
Code works fine if I move it out of a transaction.
I've been struggling with this for 4 days now and have got no closer.
Perhaps you have an issue with MSDTC?
I'd lean more towards a coding error though, because the TransactionScope object should be initialised and non null, but it will be indicating an error.
Perhaps showing us the code might help us further?
UPDATE: I've had experience with logging engines failing to log the line before an exception, which is sometimes caused by release mode reordering, or the routine doesn't flush actively and the app crashes nastily before it can complete.
I would suggest placing a logging line directly after you using() statement to assert that the TransactionScope is not null. Given the way you have used the code, it is IMPOSSIBLE for the result of that code to return null, the constructor must throw an exception if the constructor fails, otherwise you have a non null transaction scope.
Perhaps a little more code and this test might help some more?