 |
|
 |
I read through the posts that pertain to this topic. I understand what you are doing as far as catching exceptions from within the application Would you be able to help with this question
Hi
I launch a program using the code below in Windows CE 6.0 I would like to detect Missing method exceptions that may be thrown from the exe if one of the dlls it is dependent on does not exist.
WCHAR pszFileNameA [MAX_PATH] = {'"', '\\','H','a','r','d',' ','D','i','s','k','\\','A','2','M','C','_','C','E','.','e','x','e', '"','\0'};
SHELLEXECUTEINFO sei = {0}; sei.cbSize = sizeof(sei); sei.nShow = SW_SHOWNORMAL; sei.lpFile = L"\\Hard Disk\\A2MC_CE.exe"; //sei.lpFile = pszFileNameA; WriteStringToActivityLog("\nLaunching A2MC_CE.exe"); if(ShellExecuteEx(&sei) != 0) { WriteStringToActivityLog("\nA2MC_CE.exe successful"); } else { subc.Write("A2MC CE Failed E960"); WriteStringToActivityLog("\nA2MC CE Failed E960"); }
Here is the beginng to the exe where I have tried to catch them inside the exe. The missing method exception always gets thrown and caught by the OS in a debug window. The operating system must be trying to load the missing dll that the exe is dependent on before the code below runs. Does anyone now how to catch these missing method exceptions? Is there a way? I want to be able to detect when my exe is missing components and do something about it rather than getting a debug message window.
static class Program { /// <summary> /// The main entry point for the application. /// </summary> static void Main() {
try { Console.WriteLine("Run the app"); Application.Run(new A2MotionControllerGUI()); } catch(MissingMethodException e) { // Show the user that the DoSomething method cannot be called.
Console.WriteLine("Unable to call the method: {0}", e.Message); MessageBox.Show("Unable to call the method: {0}", e.Message); }
} } }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I read through the posts that pertain to this topic. I understand what you are doing as far as catching exceptions from within the application Would you be able to help with this question
Hi
I launch a program using the code below in Windows CE 6.0 I would like to detect Missing method exceptions that may be thrown from the exe if one of the dlls it is dependent on does not exist.
WCHAR pszFileNameA [MAX_PATH] = {'"', '\\','H','a','r','d',' ','D','i','s','k','\\','A','2','M','C','_','C','E','.','e','x','e', '"','\0'};
SHELLEXECUTEINFO sei = {0}; sei.cbSize = sizeof(sei); sei.nShow = SW_SHOWNORMAL; sei.lpFile = L"\\Hard Disk\\A2MC_CE.exe"; //sei.lpFile = pszFileNameA; WriteStringToActivityLog("\nLaunching A2MC_CE.exe"); if(ShellExecuteEx(&sei) != 0) { WriteStringToActivityLog("\nA2MC_CE.exe successful"); } else { subc.Write("A2MC CE Failed E960"); WriteStringToActivityLog("\nA2MC CE Failed E960"); }
Here is the beginng to the exe where I have tried to catch them inside the exe. The missing method exception always gets thrown and caught by the OS in a debug window. The operating system must be trying to load the missing dll that the exe is dependent on before the code below runs. Does anyone now how to catch these missing method exceptions? Is there a way? I want to be able to detect when my exe is missing components and do something about it rather than getting a debug message window.
static class Program { /// <summary> /// The main entry point for the application. /// </summary> static void Main() {
try { Console.WriteLine("Run the app"); Application.Run(new A2MotionControllerGUI()); } catch(MissingMethodException e) { // Show the user that the DoSomething method cannot be called.
Console.WriteLine("Unable to call the method: {0}", e.Message); MessageBox.Show("Unable to call the method: {0}", e.Message); }
} } }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
The reason that you are unable to catch MissingMethodExceptions is because the exception is thrown during the JITting fase and not during normal code execution.
So the following won't be possible public void Method1() { try { SomeMissingMethod(); } catch (MissingMethodException) { } }
Since JITting works on a per method basis, I can imagine that the following could be possible though, but I personally would not recommended relying on this behavior even if it does seem te work. It possibly won't continue to work on future versions of the .NET framework and it probably won't work at all when using NGEN: public void Method1() { try { Method2(); } catch (MissingMethodException) { } }
public void Method2() { SomeMissingMethod(); }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
 | Caution  michael rempel | 12:38 17 Nov '06 |
|
 |
Out of an abundance of caution, I would suggest you call this method as soon as you instantiate the class that it is part of. The reason for this is to ensure that it has memory allocated. I know that simple types and static methods should not allocate memory, but I never trust compiler designers to that extent. Sometimes they 'just borrow a little memory' temporarily and a routine you think is safe, in fact is not.
Another caution to programmers who may not get this thing, even if you are confident this is 'the list' of critical messages, you are not always better off working this way. Bad things happen, but often not in isolation. Your code may be messed up by some wild pointers in native code, or some other nasty unexpected condition. It is not always safe to assume that things are not out of hand, especially with exceptions like this. So in the event that a really bad problem was happening in code, you would have to design so that this exception handler could be turned off, or removed from code in order to track it down.
Michael Rempel
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Thank you for explaining the "Do Not Catch Exceptions That You Cannot Handle" rule - perhaps MSDN or www.asp.net should put your code up as "article of the day"! It is however, not just a C# problem, but affects VB.NET (and proabably every dot net language.) In many situations (such as a web application), there come a point going up the call stack, that the error detail must be replaced by a bland "there has been an error - please contact support.". Manifestly, the routine that caught the error must log it in as much detail as neccessary (preferably to a custom event log) and then set an error return code. As this error return, ascends the call stack, various other pieces of information may need to be logged as warning messages to the event log.
|
| Sign In·View Thread·PermaLink | 2.33/5 |
|
|
|
 |
|
 |
After reading through the article and the various posts replying to it, I can see the usefulness of the IsCritical approach within any given class library, however, the comments on hiding the exceptions are quite valid. I ended up inadvertently hiding an exception within a library in a recent project and it took ages to track down the problem.
An alternative approach here would be to do something like this...
class MyLibraryException : System.Exception { public MyLibraryException(Exception innerException) { if (IsCritical(innerException)) { isCritical = true; } else { isCritical = false; } }
private bool isCritical;
public bool IsCritical { get { return isCritical; } set { isCritical = value; } } }
This kind of root exception then provides the recommendation of criticality, according to the library, to the application developer but it doesn't constrain the developer or hide any information from them.
This solution relies on effectively catching everything and rethrowing at least a MyLibraryException. This can then be interrogated for criticality and the nature of the innerException. The app developer can then do whatever they want with the caught exception, including throwing the innerException.
Keith Jackson Developer S-Cool Ltd.
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
 |
I agree with your point of view. There are situations when it is not doable to catch all exceptions explicitly, and where the "any unknow exception is fatal" approach is not feasible, so it should be possible to deviate from the rule.
However, I do not quite agree with the list of exceptions that you check for criticalness.
BadImageFormatException: This exception is thrown when unmanaged code is passed to Load for loading. It can be used to check if a file is an assembly, there is a Microsoft How to example for that somewhere.
AppDomainUnloadedException: This one happens when you create a new application domain, unload it again and try to access it afterwards. This shows a problem with the application logic. CannotUnloadAppDomainException: It just says that you cannot unload the application domain for various reasons.
These three are not critical in the sense that the rest of the application could not proceed. Of course, they can show problems with your 'unattended job loading and execution code', but still we can try to proceed with the next job, especially if we think of them as being caused by such a job.
InvalidProgramException: Even this one is not critical in all situations. It depends: If it is happening in your code, it is very critical. If it is happening in the job to be carried out, possibly after loading a plug-in that was built with an unknown tool, just state failure of this job and continue.
ThreadAbortException: The documentation says "ThreadAbortException is a special exception that can be caught, but it will automatically be raised again at the end of the catch block". But it certainly does not hurt to have it here.
StackOverflowException: This one is not in your list, and for 2.0 it is not necessary: "Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default. " You might want to add it for version 1.1 code, though.
So the only two really critical ones are ExecutionEngineException and OutOfMemoryException. The latter one can be avoided with the new MemoryFailPoint class.
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
 |
I'm suprised that you didn't list ThreadAbortException as critical. If you catch that exception in a backgrond thread, then your application will not close. It will look closed, because the main form will disappear, but the app will still exist in the task list.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
You're right. I should have added ThreadAbortException. I will update this article with this exception as soon as possible. Thanks for your feedback.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
When writing unattended apps, I have had a problem with exception dialogs appearing on unhandled or unanticipated exceptions. When there is no user present, this may halt a system and prevent a possible recovery. I have tried many different APIS to catch all exceptions and simply log them or e-mail them and then terminate and restart the system. Somehow, there is always an exception that manages to "squeak by" and display a dialog box. I finally had to install my own CLR exception handler at the OS level because I could not always stop exception dialogs from coming up.
Granted, this does not solve extremely unrecoverable errors like disk full, but it at least allows an unattended system to have the change of staying up and recovering vs. sitting there waiting for someone to press OK to continue.
Although most people would say don't write code that causes exceptions, the fact is that you cannot account for all exceptions, especially if you are using 3rd party assemblies.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,
Can you elaborate or post some code if possible on "Installing own CLR exception handler at the OS level". Seems it would be very helpful in one of our applications.
Thanks Sujith Jagini
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
 |
well i'm not sure what varnk meant, but here are some suggestions.
-- There are some events you could add a handler to, such as System.Windows.Forms.Application.ThreadException and System.AppDomain.CurrentDomain.UnhandledException.
-- In your main loop:
static void Main() { try { Application.Run(new MainForm()); } catch ... }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
First, I've noticed that the MFC designers don't follow the "don't eat exceptions you don't understand" rule. Their windows message handler catches CException, calls ReportError on it, and then deletes it. It seems that even the MFC team feels that the rule is not doable.
I've also found several situations in which displaying a message box is not an acceptable solution. If the code for drawing on a window throws an exception, for instance, a message box would allow the window to be drawn again before the user can press OK. However, one can still draw the text of the exception, and in C#, one could presumeably draw the stack trace as well. Another place is in ON_UPDATE_COMMAND_UI handlers. I haven't found much solution for that except to eat the exceptions.
The simple solution of loging info about exceptions that occur in a batch process seems at least as reasonable as MFC aproach of displaying a message box for anything that goes wrong. In fact, I think it's more so, since loging info about an exception won't cause the same exception to occur again.
Nathan Holt
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
It's nice to know that Microsoft doesn't follow their own rules. I've seen that before. Try running Microsoft FxCop against Application Blocks written by Microsoft and see if they pass. 
I don't really know MFC. Does it have any code that does show the 'good'-way of doing things? Perhaps we can convert that to C#...
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
Michael Vanhoutte wrote: I don't really know MFC. Does it have any code that does show the 'good'-way of doing things? Perhaps we can convert that to C#...
I don't know myself. While I've used MFC for years, I haven't studied the examples much. I usually look up classes and methods in the MSDN library.
Nathan Holt
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
My understanding is that they are trying to clean up the old C++ MFC behavior as they continue to replace it with Windows.Forms. They recognize that the specific problem you mention in the message handler is considered a bug and they're planning to fix it. From the June 2004 MSDN article "Unexpected Errors in Managed Applications":
http://msdn.microsoft.com/msdnmag/issues/04/06/NET/default.aspx
In certain cases, exceptions that are unhandled are swallowed whole by the CLR (although this behavior is changing in the .NET Framework 2.0). Here is a summary of the unhandled exception handler default behaviors that are executing in this application. - Unhandled exceptions that occur on the
application's main thread cause the application to terminate. - Unhandled exceptions that occur in threads
other than the application's main thread are swallowed by the CLR. This includes manual threads, thread pool threads, and the CLR's finalizer thread. If your application is a console application, the CLR outputs exception text to the console (though your application keeps running). If your application is not a console application, there is no outward indication when an exception occurs and your application keeps running. - Unhandled exceptions that occur on a thread
that is pumping window messages via the Windows Forms classes are subject to the Windows Forms unhandled exception handler. A debug dialog box is produced by default, but this behavior can be overridden (more on this in a moment).
Byron Jenings
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
It seems to me that a new system could create a different kind of critical error, which your function wouldn't have caught. Perhaps a part of the problem is that the exception hierachy doesn't provide a way to distinguish minor exceptions from critical ones. I seem to recall that the standard C++ library exception system does have a badexception class or something like it that could be checked for. On the other hand, what a library designer thinks is a bad exception may not be what you think is a bad exception. I've had to deal with annoying exceptions thrown if I move to the beginning of an empty recordset.
Nathan Holt
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
A badexception-class would solve some of my problems but I agree that there could be some discussion between developers as to what a critical exception is. To me a critical exception is one that I can't possibly recover from gracefully. For example if my dll is corrupt. I personally would think that 'out of memory' is also a critical exception, but some application might decide to clear their cache when this exception occurs. That is an 'advantage' of the IsCritical-method: you can decide for yourself... Still I agree, it's far from ideal.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
We have the same problem with VB6. And it's worst because it throws error numbers rather than exception classes. I came with the solution to build an error handler library. When an error occurs, I call a static method named "TrapErr". Once an error is trapped, I can do some operations then decide to rethrow the error to the calling procedure or to add an entry in the log file or to display a message box with the possibility to see the details of the error. I also came with the conclusion that each errors that occurs in a component should always be treated internally and that component should always throw its own errors to the clients, with desired detailed informations on the error passed back. This worked very well for me.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Yes and no. If the form fails to display, it displays a message box instead. In the case of a stack overflow, the library could never be called, naturally. If there is no enough resources, the library could fail to do its job. I could prevent this by allocating the resources at the beginning of the program, but it never happens to be a common error. In either case the program will fail though.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Personally, I disagree with your statement that it is not doable to catch all of the exceptions explicitly. But, for the moment let’s say you are correct.
The one problem that I see with your way of catching and checking errors could still mask a problem. If there is a problem in the code that you are calling, whether it is a Microsoft method, a third party method, or one of your own methods and if the called method does not throw an expected exception then the code checking for the exceptions will still mask the error.
If you must generically catch exceptions, then you should look for the exceptions that you expect and wish to ignore (the non-critical ones). Any other exception that is given to you then must be a critical one regardless if it was in the documentation or not.
Just my opinion. Jim
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
 |
Jim, thank you very much for your feedback. It's always interesting to hear somebody else's opinion about this matter.
I agree that you should always attempt to catch specific exceptions. Needless to say that I've given this matter a great deal of thought before I came up with the 'solution' that I described above. Let me give you a specific scenario of where I would use it and I would really appreciate any insights on how you might handle this situation.
Recently, I've started converting an API that I've written in VB6 to C#. The VB6-API has about 150.000 lines of code and about 2000 properties, methods, events... You can summarize all this as: "a lot of different things can go wrong" . Another thing that this application has is a Maintenance-module. The purpose of this module is to execute long-running tasks during the night. It has two important advantages: 1. Everything that you can do using our API can also be done using this maintenance module. 2. A customer can also extend this maintenance module using his own custom code.
So, in the maintenance module you have the following code (simplified naturally): foreach (MaintenanceTask objTask in AllMaintenanceTasks) { try { objTask.Execute(); } catch (Exception ex) { Log(objTask.Name + " failed to execute."); } }
Needless to say that objTask.Execute could theoretically throw hundreds of different exceptions since every exception that could possibly be thrown in our API could be thrown by objTask.Execute(). And because customers extend objTask.Execute() with their own code, I don't even know at design-time all the exceptions that objTask.Execute() could throw. Naturally, I want my maintenance-module to continue running regardless of what went wrong in objTask.Execute(), unless that it is a really, really, really important problem.
How would you handle this scenario?
Or another more simple example: One of the methods of my API is called Application.Login; it can be used by a user to log into a database. In this method, the following problems cause exceptions to be thrown: invalid license key, invalid username, can't connect to database, invalid database, wrong password, filesystem io-error, .NET remoting errors... Somebody using our Login-method just wants to know if his logged in or not. Should I expect all my customers to catch all these exceptions individually? That first of all complicates development for these customers a lot. And, they might have problems if I need to throw yet another exception in a newer version because they wouldn't catch it. As a workaround, I could put all the code of my Login-method in a try-catch-block and throw a more generic UnableToLogin-exception for everything that can go wrong. However, I don't really want to do that because I loose a lot of detail then.
Again, I don't know of a good way to handle this situation. How would you?
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |