Can a c# service crash if there is a catch all - c#

I have a service that is started using a start routine surrounded by a try catch block as below.
protected override void OnStart(string[] args)
{
try
{
Program.Start();
}
catch (Exception e)
{
Logger.Error("Exception during Service Start");
}
}
Occasionally on some machines (1/100) it will occasionally print out the last line of Program.Start (a log message) and then fail with no log messages or event log messages. Should this be possible?
Thanks
EDIT: The service does kick off a few other threads but they are encapsulated in the same manner
EDIT: The Logger is a wrapper for log4net - it's working very reliably on a lot (100+) of machines (though yes it possibly the cause)

The service could crash if an exception is thrown out of a started thread but not caught.
Are you adding a handler to each app domain unhandled exception?
eg:
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler( CurrentDomain_UnhandledException );
EDIT
Also, you have the Application.ThreadException event which i forgot to mention:
http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx

If the program crashes or an exception is thrown from try block, then for sure youll get Logger.Error log info but not the eventlog from system. If service crash or an unhandled exception occurs, then only eventlog on service is logged.

Yes it could be possible. For instance, a StackOverflowException cannot be catched since .NET 2.0 (see the MSDN article about it).

I am not clear on your question but if you are asking whether your app can crash with a skeleton like that, the chances are very less. Since you have a catch all block almost all kinds of exceptions would be caught and thus your program would end gracefully.
How ever if its a repetive scenario that you are aware of it'd be better to handle it the known way then achieve what you want with an exception as generally execptions for times when something unknown might occur.

Can you put the call to your Logger component in a try-catch block and let us know what happens? Are you able to monitor your service without the Logger component (i.e., based on whatever ouput the service is supposed to be produce - like DB updates)?
Try writing to the event log directly if the call to your Logger component fails. Put this in a try catch block as well. Since the Logger successfully wrote the last line in Program.Start(), it may be something related to unsuccessfully attempting to dispose a resource or something similar, and this is not getting logged.

Related

Application shutting down without notice

I am currently managing a complicated application. It's written in C# and .Net 4.7.2.
Sometimes this program shuts down without notice. No error message even with a try/catch block and MessageBox.Show() in the Main method (I know it's probably not the best way but should work).
There are several threads running at different points, calling external DLLs and sometimes even drivers. So in order to log whether it's another thread that crashes the whole thing, I do this at the beginning :
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
Application.ThreadException += Application_ThreadException;
Because I'm not sure which one is the correct one. In the methods, I log the Exception (after performing null checks) into a file (using File.AppendText and a timestamped based file).
Still nothing. The application keeps crashing after some random amount of time (between 2 and 6 hours) and I have no log information, no error message and I'm getting kind of lost here.
The app is running in Release mode and I cannot use Visual Studio to run the debugger into it (because that would make it easy). Maybe there's another way to run an external debugger ?
Can someone give me a hint on how to catch up for an exception that would cause an application to crash silently ?
Based on your explanations the only thing that brings to my mind is that you have some fire and forget threads in your application that throw exception sometimes but your application can't keep track of them to log or catch their exceptions.
Make sure all your tasks are awaited correctly and you don't have any async void method.
If you really need some fire and forget actions in your app, at least keep them alive with something like private Task fireAndForgetTaskAliver in your classes.
Another probability could be memory leak in your app that causes stack overflow exception.
The only way to catch an exception that is not caught anywhere in the code is indeed to look it the Windows Event Log, under Applications.
Thanks to Pavel Anikhouski for his comment.

Error reporting through custom exception bubbling

I have a chain of C# applications/services communicating through WCF, and one MVC web application that can sometimes instigate actions along this chain of services.
What I want is a safe way of reporting useful errors that happened along this chain, once a web app user instigated an action that resulted in an exception. My current solution is catching any Exception as soon as possible, then creating a CustomException with a custom message that best identifies the causing problem. This CustomException will propagate up the service chain (serialized at the service boundaries using a [FaultContract (typeof(SerialisedCustomException)]) by try/catch blocks. When an Exception is caught at any point, if it is of type CustomException it'll be rethrown. Otherwise a CustomException will be created on the spot, as above, then thrown further.
As a use-case, let's assume that a user logged in to my web application A performs an action which tells service B to tell service C to create a file on C's filesystem. (the actual actions are more complex than this, and more than one thing can go wrong, but I think this is a sufficient example)
If anything goes wrong along the way, I want the user to be informed of it in such a way that he can remedy the problem.
By safe, I want only errors that I have specifically created (hence my usage of a CustomException) be shown to the user, and nothing else (if a System exception, say UnauthorizedAccessException, gets thrown, I will wrap it in my own CustomException and only show the end-user the message of my own CustomException. I do not want any Exception messages that potentially expose implementation details be shown to the user.
By useful, I want to show the user an appropriate message and suggestion, such as 'make sure you have the right permissions etc.', as opposed to 'Service B says: Internal Server Error'. (These would be set the moment the CustomException is first thrown, and not altered on further catch/throws. If debugging is enabled, I'll be also displaying a stack-trace, but in production I will only show my safe custom message).
The problem with my approach is that the more and more I write try/catch blocks around my service methods, and in the methods they are calling, and so on, the eeriest I feel that this is not the right way to go, and that there's a better, more efficient/less bloated solution out there.
Is there anything that solves this problem while also avoiding the overhead of wrapping everything in try/catch blocks ?
Edit: Added justification for the need of reporting the errors rather than saying 'Something went wrong, we're looking into it.'
My web app can instigate complex (and customizable) actions on the lower-level services. These can fail for plenty of reasons which can be fixed by tweaking the customization of that action.
As an example, let's say I have an action that copies a a user-inputted source file to a user-inputted destination (on machine C, or on a network drive accessible to machine C). For various reasons (file not found, network down, lack of permissions, not enough disk space etc.), this action might fail, but some of the reasons could be fixed by the user changing that custom action, if only they were able to see why it failed in the first place.
You do not need to try...catch everything, you only need to catch only expected exceptions to wrap them in an CustomException and add a useful message to them, otherwise they should be catched in the caller (or caller of caller and so on) method.
Also you do not need to catch CustomException and re-throw it. It just bubbles up even if you don't catch it. Only problem is WFC Services throw FaultExceptions only. You can catch those exception in the most outer call only.
And to have useful exceptions, you can simply provide a detailed message for the exception, specify an ErrorCode property for CustomException or define nested exceptions like CustomException1 and CustomException2 inheriting CustomException. In the UI level you can resolve user friendly error message from that error code or exception type.
For example:
Web Application A:
void UserAction(string input) {
try {
serviceB.RespondToAction(input);
}
catch (FaultException e) {
if (e.InnerException is CustomException) {
DisplayMessageToUser(ResolveExceptionMessage((CustomException)e.InnerException));
}
}
catch (CustomException e) {
DisplayMessageToUser(ResolveExceptionMessage(e));
}
}
Service B:
void RespondToAction(string input) {
try {
SomeOperation(input);
}
catch (FormatException e) {
throw new CustomException("Invalid input format.", e);
}
// Note you do not catch CustomException here...
// Note you do not use try-catch here...
serviceC.CreateFile();
}
Service C:
void IOOperation2() {
try {
IOOperation();
}
catch (IOException e) {
throw new CustomException("Failed to create file.", e);
}
catch (SecurityException) {
throw new CustomException("Failed to create file.", e);
}
// Note you do not catch an ExecutionEngineException here...
}
From my experience exceptions are rarely useful for communicating information to the end user. 'make sure you have the right permissions etc.' sounds more like a business rule type of handling than exception type.
I don't often encounter the need to propagate exception through layers either. There are scenarios where that could be useful, but most of the time they can be logged at the site where they are caught.
And the caught clause is usually used very sparingly, that is it is not uncommon for a web application to only have a single global exception handler and that's it.
The main purpose of the exceptions is to tell the support personnel what have gone wrong. That mainly either a) infrastructure conditions (server is down, database is down, etc) or b) bug in the code. Everything else usually falls into the bucket of business errors and processed as such.
There are edge cases when the above is not enough, for example if you are consuming a service or a library that you don't have control over and this server/library makes use of exceptions to communicate results of an operation. But that's rare.
The way I design my exception handlers is to always start with a single global one (per application). Then if during testing exceptions are found, I look into them and try to classify them. Is this exception because of a bug? Then I fix the bug. Is this exception because of infrastructure condition? Then perhaps need to log it, show appropriate message to the customer and perhaps notify support. In this case a custom error handler can be warranted, however often a generic "we have a error we are looking into it" message and the support notification is enough, in this case a custom error handler is not needed either. Note that in the described situation the end user can't really do anything about the issue but wait. Lastly if the exception is because of business conditions then I see if I can re-design the code path so that no exception is thrown for business type errors. If it's my own code this is not a problem (and I won't have this situation to start with), if it's a library/service, then yes, might need to wrap the call into a try/catch.
As the result of the above approach my code have very few exception handlers, and I like it this way - if disaster happens it's usually immediately clear where as the stack trace pinpoints the exact location, and there is no messy nested exceptions to consider.
Note: for a library author the considerations could be slightly different

.NET exception not caught

I have a function that looks like this:
try
{
_dbManager.InsertSearch(some data);
}
catch (Exception ex)
{
//do logging
}
_dbManager uses LINQ to insert data to a SQL database. Yesterday, the machine that hosts the database ran out of hard disk space and my program crashed. I got a crash dump which shows that there was a SqlClient.SqlException raised with an exception message reading something like "Database transaction log is full...".
My question is: Why didn't the exception get caught in the catch block above? The weird thing is, when I tried to reproduce the issue, I could get the same exception, but it was caught by the catch block. What could be the issue?
Second, related question: Imagine if we use a third party library and we don't want any exception thrown. We can use try-catch block, but this only works on calling thread. What if the third party starts new thread and an exception is thrown there? Is there a way to handle this? I know I can register our UnhandledExceptionHandler, but that seems to be a different from what I wanted.
My question is: Why didn't the exception get caught in the catch block above?
As David Stratton suggests, the system might have been out of disk space and not able to write to log file. There is also a chance that the process was terminated due to Corrupted State Exception that will not be delivered to your catch-all block in .NET 4. The exception that terminated process might have also been thrown from the thread that did not have catch-all.
Second, related question: Imagine if we use a third party library and
we don't want any exception thrown.
I think that you will have to stop right there and rethink it. What you saying is that you are absolutely 100% sure that nothing ever can go wrong in the thirdparty library. There are certain exceptions (like OutOfMemoryException) that you should not be catching because your code simply does not know how to recover from them. The rule of thumb with exception handling is that you should only catch the exceptions that you fully understand and know how to recover from. Please take a look at this answer and the links in it.
What if the third party starts new thread and an exception is thrown
there? Is there a way to handle this?
The best way to handle this is to rely on default CLR policy that will terminate your application. The only reasonable thing you can do is try to log it by subscribing to AppDomain.UnhandledException.
Is it possible that there is another try/catch block inside that InsertSearch method, which has conditional throw statement.
The implementer of the 'DBManager' class, chose not to throw in case there is not enough space to write on the disk. Just a thought.
If you use Code contracts runtime checking I advice you to check compiled version of your DLL.
Read this for details Why .net exception is not caught?

What does "Only catch exceptions you can handle" really mean?

I'm tasked with writing an Exception Handling Strategy and Guidelines document for a .NET/C# project I'm working on. I'm having a tough go at it. There's plenty of information available for how/when to throw, catch, wrap exceptions, but I'm looking for describing what sorts of things should go on inside the catch block short of wrapping and throwing the exception.
try
{
DoSomethingNotNice();
}
catch (ExceptionICanHandle ex)
{
//Looking for examples of what people are doing in catch blocks
//other than throw or wrapping the exception, and throwing.
}
Thanks in advance
It means exactly that. If you are expecting code you're running to throw an exception, and when that exception is thrown your code knows what went wrong and how to proceed, then catch the exception and handle it.
Basically, the rule exists to prevent anti-patterns like:
try
{
...
}
catch(Exception ex)
{
throw;
}
The catch here does nothing but add a speed bump to unwinding the call stack. If you don't actually want to do anything with the exception you're catching, you shouldn't even bother with the catch.
A related but far more valid case is where you don't care about the exception being thrown, but you need to clean up in all cases. In that case, skip the catch; you don't need it, just make it a try-finally block.
EDIT: To answer the question in the post, not just the subject, you could write a rule as follows: "Do not code a try-catch statement that does not do anything, or only rethrows the caught exception. All catch statements should perform some value-added action relating to the thrown exception."
For example, let's say you are trying to connect to a SQL Server instance using credentials supplied by the user when they log into your app. Dozens of things could go wrong, some of which you can't expect, some of which you should.
Server isn't responding - you can try again; perhaps call the connection method recursively in the catch, with a "retry counter" to break the otherwise infinite loop.
User failed authentication - show a friendly (or not-so-friendly, but concise and understandable) message in red on the dialog box.
User not authorized to connect to the specified DB - Depends on your security setup; in most offices, that's something you should e-mail the DBA about because it means he created the login but forgot to assign the proper rights.
Network not available: You can alert the user through an error on the login dialog or a new dialog, retry a couple of times, etc.
Division by zero - WTF? What could possibly cause a Div by Zero during a login? You're not expecting this exception, you have no clue what went wrong in this case and therefore can't continue running code, so don't catch it.
If anything goes wrong, you may want to log the message to a file or a shared resource for audit/security purposes. This should happen at lower levels if you want to continue execution, or higher levels if you're going to gracefully shut down afterward.
All of these examples involve first catching the exception of a known type and interrogating it to see what exactly went wrong, then performing some known action that can allow the program to continue execution. The object is to prevent the application from crashing and burning when something goes wrong that you know could go wrong, but know how to keep the program running in that case.
The basic rules for catching exceptions:
If you aren't expecting an exception, don't catch one.
If you can't or don't want to continue execution of code after receiving an exception, whether you know it can happen or not, don't catch it.
If you are expecting the exception to occur, and know-how to continue executing code when it happens (at least for a while), then catch and perform any special actions you need in order to do so.
NEVER trap exceptions (an empty catch block); that causes applications to fail silently in even more unpredictable ways.
NEVER leave catch-and-rethrow (a catch block with only a rethrow) in production code. They can sometimes be useful when debugging as they allow you to identify specific segments of code that are failing, but in production code, they're just a speed bump to throwing out or actually dealing with the exception.
I think the basic idea underlying this common piece of advice is to avoid scenarios like this:
try
{
SomeImportantResource = GetSomeImportantResource();
SomeOtherImportantResource = GetSomeOtherImportantResource();
}
catch (Exception ex)
{
SomeGlobalErrorHandlingMechanism(ex);
}
I've worked with developers who, when confronted with a bug, would simply wrap the offending code in a try/catch block and say, "I fixed the bug." The problem in scenarios like the above example is that by simply catching an exception and not fixing the problem that caused it, you're liable to undermine the solidity of your program. Above, what the catch has done is made us uncertain whether SomeImportantResource and SomeOtherImportantResource were ever initialized properly. It seems likely that there could be code elsewhere in the program that requires for these to be initialized, in which case, we've just introduced a bug by "fixing" a bug.
So I think the standard wisdom is to only try to deal with an exception if you can recover from it in such a way that it does not compromise any other code elsewhere in your program.
Or, better than that: don't catch the exception and make some feeble attempt (or non-attempt) to "handle" it; figure out what caused it and fix that problem. Obviously this is not always possible, but it is possible a lot more often than it should be.
Consider if you had an application like OneNote that lets you store your files on a shared network drive, but in the event the network is unavailable, then it uses local storage temporarily until the main storage is available.
If your program got an exception while interacting with the files, then you could retry the action with the local storage.
This is an example where you have a specific program behavior you want, and accomplish it by how you handle the exception. Generally, you should try to find a way to accomplish your goal without using exception handling, such as in the above exmple, you could always check to see if the file is available before attempting to operate on it. That way you can just code it as an "if/else" instead of a "try/catch". However, if you did that, there is still always the chance in the above case that someone may lose access to a file in the middle of an operation, such that regardless of whether you checked in advance, you still might get an exception that you can handle gracefully. So you'd probably refactor your else block into a function that is both called from the else and the catch, so that you can gracefully fallback to local storage in either case.
I also often include logging if there is no security issue with what I'm logging, and a rethrow as you mentioned, and my logging includes more descriptive information and context information, maybe some local values, which make debugging easier. I always strive to have log files so detailed that I can determine the cause of a problem without having to reproduce on my machine. I hate hearing programmers make the "I can't reproduce it" excuse. You don't have to reproduce it. If your logging is adequate then there is no need to reproduce it.
When an exception trickles up via rethrow's all the way to your GUI layer, then at that point is where you catch it and do not rethrow it, but instead display a message to the user indicating that an unexpected error occurred, and usually exit the application. You might give them an opportunity to save work, but maybe automatically making a backup of the file being overwritten, as an unhandled exception is something you never coded for, meaning something might be corrupt, and you might be saving a bad file, yet leading the user to believe they are saving their work. This is ultimately the reason many program opt to kill themselves if something unexpected occurs, as from that point on who knows what state the program might be in, and something as simple as saving some rows in a database might have serious consequences and hose alot of data.
If you can perform an action when you catch an exception that is helpful in some way (such as executing a block of code that will perform the function attempted in the try statement, but does it in a different, but perhaps less efficient way, or simply informing the user that their action couldn't be performed), then you should catch it and do so. If you are simply logging the exception to track down the problem later, then you should rethrow the exception throw; (NOT throw ex;), in case there is another block of code that can handle that type of exception.
It's also acceptable to catch an exception to wrap the caught exception in your own exception that may make more sense to the calling function.
Some examples:
Log the exception and just carry on
Retry the thing that went wrong
Try another method of doing what you were trying to do
It all depends on what went wrong. The point is, just catching and re-throwing is of no use to anyone.
If your code can gracefully handle a specific type of exception, catch it and handle it, and then let your code keep going. If not, let the exception propagate up, because it may be caught at a higher level or it may be something really wrong that you shouldn't be catching as it might mask the error.
You shouldn't catch an exception you can't handle, but you can catch exceptions that you might be able to handle:
try
{
DoSomethingNotNice();
}
catch (ExceptionIMightBeAbleToHandle ex)
{
if(iCanHandle(ex))
thenHandle(ex);
else
throw;
}
Note that using throw by itself is supposed to preserve stack trace info.
Typical things you can handle gracefully would be a FileNotFoundException.
The catch block should teardown anything that may have been opened for use in the try and due to the exception being thrown not closed down properly. Database connections and file access are the ones that usually need closing down (though proper use of a using block can handle this)
Once that has been done you can use throw; to chuck the exception up to the next level
Alternatively you might want to wrap your current exception inside a new exception more relevant to the current method
catch(LowLevelException ex){
throw new HighLevelException("argh bad things happened!",ex);
}
Coming late to the game but the MS recommended way to handle errors globally in .net core is middleware.
Also you can use a switch statement like this to make sure you re-throw errors you can't handle.
Trying to keep my answer as general as the question ;) but I can provide some code if needed.

How to catch ALL exceptions/crashes in a .NET app [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
.NET - What’s the best way to implement a “catch all exceptions handler”
I have a .NET console app app that is crashing and displaying a message to the user.
All of my code is in a try{<code>} catch(Exception e){<stuff>} block, but still errors are occasionally displayed.
In a Win32 app, you can capture all possible exceptions/crashes by installing various exception handlers:
/* C++ exc handlers */
_set_se_translator
SetUnhandledExceptionFilter
_set_purecall_handler
set_terminate
set_unexpected
_set_invalid_parameter_handler
What is the equivalent in the .NET world so I can handle/log/quiet all possible error cases?
You can add an event handler to AppDomain.UnhandledException event, and it'll be called when a exception is thrown and not caught.
Contrary to what some others have posted, there's nothing wrong catching all exceptions. The important thing is to handle them all appropriately. If you have a stack overflow or out of memory condition, the app should shut down for them. Also, keep in mind that OOM conditions can prevent your exception handler from running correctly. For example, if your exception handler displays a dialog with the exception message, if you're out of memory, there may not be enough left for the dialog display. Best to log it and shut down immediately.
As others mentioned, there are the UnhandledException and ThreadException events that you can handle to collection exceptions that might otherwise get missed. Then simply throw an exception handler around your main loop (assuming a winforms app).
Also, you should be aware that OutOfMemoryExceptions aren't always thrown for out of memory conditions. An OOM condition can trigger all sorts of exceptions, in your code, or in the framework, that don't necessarily have anything to do with the fact that the real underlying condition is out of memory. I've frequently seen InvalidOperationException or ArgumentException when the underlying cause is actually out of memory.
This article in codeproject by our host Jeff Atwood is what you need.
Includes the code to catch unhandled exceptions and best pratices for showing information about the crash to the user.
The Global.asax class is your last line of defense.
Look at:
protected void Application_Error(Object sender, EventArgs e)
method
Be aware that some exception are dangerous to catch - or mostly uncatchable,
OutOfMemoryException: anything you do in the catch handler might allocate memory (in the managed or unmanaged side of the CLR) and thus trigger another OOM
StackOverflowException: depending whether the CLR detected it sufficiently early, you might get notified. Worst case scenario, it simply kills the process.
You can use the AppDomain.CurrentDomain.UnhandledException to get an event.
Although catching all exceptions without the plan to properly handle them is surely a bad practice, I think that an application should fail in some graceful way. A crash should not scare the user to death, and at least it should display a description of the error, some information to report to the tech support stuff, and ideally a button to close the application and restart it. In an ideal world, the application should be able to dump on disk the user data, and then try to recover it (but I see that this is asking too much).
Anyway, I usually use:
AppDomain.CurrentDomain.UnhandledException
You may also go with Application.ThreadException Event.
Once I was developing a .NET app running inside a COM based application; this event was the very useful, as AppDomain.CurrentDomain.UnhandledException didn't work in this case.
I think you should rather not even catch all Exception but better let them be shown to the user. The reason for this is that you should only catch Exceptions which you can actually handle. If you run into some Exception which causes the program to stop but still catch it, this might cause much more severe problems.
Also read FAQ: Why does FxCop warn against catch(Exception)?.
Be aware that catching these unhandled exceptions can change the security requirements of your application. Your application may stop running correctly under certain contexts (when run from a network share, etc.). Be sure to test thoroughly.
it doesn't hurt to use both
AppDomain.CurrentDomain.UnhandledException
Application.ThreadException
but keep in mind that exceptions on secondary threads are not caught by these handlers; use SafeThread for secondary threads if needed

Categories

Resources