0

I just started working on an existing big project. Some of it contains legacy code.
I have been asked to write a component (will run in the same process) which should alert and restart the server in case of a Fatal error or a situation occurred.

For example, when an OutOfMemoryException is thrown I should alert the clients and then restart the server. The problem is, it will be hard and time consuming to search for all the existing Try-catch blocks and then to edit and add new code to their catch blocks. More than that, a new programmer could add a new try-catch block and forget to alert if OutOfMemoryException is catched.

Do you have any idea on how to monitor/listen for OutOfMemoryException (and similar exceptions) without the need to find and edit (and maybe add to) every existing and future Try-catch blocks?

I'm using .Net 4.

Edit:

  1. OutOfMemoryException is only an example.
  2. There could be legacy code which catches OutOfMemoryException, prints a message to log then do nothing.
m1o2
  • 1,549
  • 2
  • 17
  • 27
  • 1
    You should take a look into this post and than rethink what your are doing http://stackoverflow.com/questions/5507836/which-types-of-exception-not-to-catch – Venson Aug 04 '13 at 11:04
  • possible duplicate of [When is it OK to catch an OutOfMemoryException and how to handle it?](http://stackoverflow.com/questions/2117142/when-is-it-ok-to-catch-an-outofmemoryexception-and-how-to-handle-it) – Cody Gray - on strike Aug 04 '13 at 11:28
  • 1
    Remember, exceptions are propagated up the stack. You don't have to have a try/catch block in every function, and certainly *shouldn't* to handle global exceptions like this one. Put the try/catch in your `Main` function, if you absolutely must do this. (I do not recommend it. This type of exception indicates your app is in a very fragile state, likely unrecoverable and impossible to reliably execute any code you have in the catch block.) – Cody Gray - on strike Aug 04 '13 at 11:29
  • Some CLR hosts handle this. ASP.NET and SQL Server kill the process/appdomain AFAIK. – usr Aug 04 '13 at 12:00
  • @CodyGray The problem with this approach is that I saw try/catch blocks which catches 'Exception'. So it also will catch an exceptions like OutOfMemoryExceptions – m1o2 Aug 04 '13 at 12:13
  • I don't know what you mean by that comment. You should never catch `Exception` because you cannot handle all possible exceptions. The only exceptions you should catch are the ones you can handle. But you're saying that you want to catch `OutOfMemoryException`. I don't think this is a good idea, but if you do, just catch that. You don't have to catch the base class, you can use a derived class there. – Cody Gray - on strike Aug 04 '13 at 12:16
  • 1
    `OutOfMemoryException` does not Always mean that the program "is out of Memory" many ( even windows intern ) lib´s using this ex to indicate other problems, for example the `Image.Load(...)` function can throw that ex ... but that does not only mean that there is not enough memory available ... there are a lot more possibility's ... but you should still consider What kind of ex handling is relay usefull – Venson Aug 04 '13 at 12:17
  • @CodyGray Sorry for my unclarity. I meant that there are legacy code which catch 'Exception'. So even If I will put the Try/catch in the Main method, Not all of the OutOfMemoryExceptions (or other Fatal exceptions) will be reach me. – m1o2 Aug 04 '13 at 12:22
  • 1
    One way is maybe to use the [`Application class`](http://msdn.microsoft.com/EN-US/library/system.windows.application.aspx) From WPF that allows you to use the. `AppDomain.CurrentDomain.UnhandledException` and `this.Dispatcher.UnhandledException ` events that allows you to handle Events on Program layer. if you Attach an Handler you can consider which exeption should be "handeled" by Windows (Crash) and with IS handeled in that Eventhandler (by setting `e.Handled`) Don't know if this is maybe a Solution – Venson Aug 04 '13 at 12:22
  • Hmm, I see. Well, that code needs to be fixed as the first thing you do. It is clearly wrong. It will solve a lot of other problems besides this. A "legacy" status doesn't give it the right to compromise the rest of your code; you still have to maintain legacy code as long as you're using it. – Cody Gray - on strike Aug 04 '13 at 12:26
  • @Venson Thanks for both of your comments. They are very helpful to me! – m1o2 Aug 04 '13 at 12:39
  • @CodyGray I will talk to my TL. You are right...We will need to define a set of rules to other programmers on which exceptions to catch. – m1o2 Aug 04 '13 at 12:41

3 Answers3

5

This is exactly the reason you should be fixing an OutOfMemoryException.. not trying to catch it. It can be thrown from anywhere.. at any time.

Besides.. it's an Out of memory exception.. what guarantee do you have that the process will have enough memory to handle it? You don't.

Simon Whitehead
  • 63,300
  • 9
  • 114
  • 138
  • The handle process could be an "exit(1)" like statement. for example. I know that it will terminate the server anyway, but it will be good to try to do some actions before the termination process. – m1o2 Aug 04 '13 at 11:09
  • So, consider the case when an OutOfMemoryException is thrown. How do you propose the framework allocates more memory for you to do anything? It is _out of memory_.. where does it allocate what it needs to call a function / "do some actions before the termination process"? – Simon Whitehead Aug 04 '13 at 11:11
  • You are right. It could be problematic to do anything of handling in this situation. Probably will only need to terminate the program. – m1o2 Aug 04 '13 at 12:15
3

One thing which is worth a shot is using an app domain approach. You create your new application, in the application you create a new app domain that executes the legacy code. Your code has a try...catch block such as

try {
    // Execute legacy code app domain.
} catch (OutOfMemoryException ex) {
    // Do whatever you need.
}

Here's some articles to help you out :

http://gavindraper.com/2012/01/31/app-domains-and-their-uses/

http://www.superstarcoders.com/blogs/posts/executing-code-in-a-separate-application-domain-using-c-sharp.aspx

As the OOM exception will occur in the app domain of the legacy app domain, it should not affect the app domain of your new code (i.e. due to Windows memory managements, virtual memory).

Jason Evans
  • 28,906
  • 14
  • 90
  • 154
  • Thanks, I will look more into this approach. One problem is that the legacy code could try to catch the OutOfMemoryException. If I understood you correctly, you are saying that in the new Application I can create a new App Domain and monitor it for OOM Exceptions ? – m1o2 Aug 04 '13 at 12:44
  • Thanks! It will do the job! – m1o2 Aug 04 '13 at 18:45
  • Sorry for the delay, I've been away for the day. In theory your app domain should be able to capture exceptions thrown from the legacy app domain. This is ideal for you, since you want to process OOM exceptions specifically. – Jason Evans Aug 04 '13 at 18:54
  • Though I need to do more research on Application Domains to check whether it could impact the performance of the application. For example a fewer memory will be considered an impact on performance. – m1o2 Aug 04 '13 at 20:00
  • 1
    Agreed. You must always prototype/research any new way of doing something. Throw away what doesn't work for you, at least you have learned of one method which does not achieve what you need. – Jason Evans Aug 04 '13 at 20:02
  • It is a gr8 attitude!! – m1o2 Aug 04 '13 at 20:06
1

[Comment Wrapper]

You should take a look into this post and than rethink what your are doing

OutOfMemoryException does not Always mean that the program "is out of Memory" many ( even windows intern ) lib´s using this ex to indicate other problems, for example the Image.Load(...) function can throw that ex ... but that does not only mean that there is not enough memory available ... there are a lot more possibility's ... but you should still consider What kind of ex handling is relay usefull

One way is maybe to use the Application class From WPF that allows you to use the. AppDomain.CurrentDomain.UnhandledException and this.Dispatcher.UnhandledException events that allows you to handle Events on Program layer. if you Attach an Handler you can consider which exception should be "handeled" by Windows (Crash) and with IS handeled in that Eventhandler (by setting e.Handled)

Community
  • 1
  • 1
Venson
  • 1,772
  • 17
  • 37