I have an application in C# that I want to run by just running the .exe from my desktop. However, I'm pretty sure there will be some type of error that will make the program crash. Is there a way to write the problem that caused the program to crash to a text file, so that I can see what caused the issue when users are using the program? I know I can use debug mode to do this but I want to run the application as a stand alone not inside of VS.
Thanks,
I am aware of the try catch blocks and I am already using those where problems might occur. But I am speaking in general. For example if I wasn't sure where the problem would occur. There is no way to print this specific error to a file.
You can try the global try/catch method except that if there is an exception on a background thread it won't be caught. You can use AppDomain.UnhandledException if you want to be notified of any unhandled exception in the appdomain (msdn). You would signup in main before the rest of your program executes like so:
static void Main(string[] args)
{
AppDomain.UnhandledException += WriteUnhandledExceptionToFile;
// rest of program
}
static void WriteUnhandledExceptionToFile(object sender, UnhandledExceptionEventArgs args)
{
// write to where ever you can get it.
string path = Path.Combine(Environment.CurrentDirectory, "UnhandledException.txt");
File.WriteAllText(path, args.ExceptionObject.ToString()); // will print message and full stack trace.
}
Edit
Note that by default Windows Forms and WPF catch any exceptions that are thrown on the UI thread. You will have to subscribe to the Application.ThreadException event (forms) or Application.DispatcherUnhandledException event (wpf) to be notified of exceptions on those threads. The code would be very similar to the code above for the AppDomain event.
Have a global exception handler that writes the exception details to a file.
If you wrap the code in your Main method in a try{}catch{} block, you can write out the exception details in the catch block.
try
{
// Calls to application code
}
catch(Exception ex)
{
// log `ex.ToString()`
throw; // rethrow to ensure termination optionally: `Application.Exit`
}
Even if you aren't logging the problem, you can usually get the error in question from the event viewer within windows.
The first thing you want to look at is the try/catch construct in C#. This is probably your first building block to handling errors.
As for how you handle the errors, that's entirely up to you. Currently your only stated goal is to log them to a file. You can get a lot of details out of the Exception object that you catch and you can write those details to a file. Additionally, you can use logging libraries to help with that sort of thing.
Proper error handling is something of a big subject, really. One thing to keep in mind is logically where you want to catch the exception. Ideally, you want to catch it where you can handle it. That is, where your code can sufficiently recover from the error. If it's a fatal error and the application should stop entirely, then you can throw the exception further up the stack and let it go unhandled (though still logged where you caught it).
If, however, you're in a logical condition where you can just log the error and move on, then the catch block allows you to do just that. Log the details, update the state of any objects/data which need to be updated, and continue with the flow of the application.
you can surround your one of the starting method with try catch block
try
{
///Your code
}
catch(Exception exception)
{
System.IO.File.WriteAllLines("ErrLog.txt", exception.Message);
}
As a permanent solution you can create extension method ToLog and use it whenever you want.
public static void ToLog(this Exception Exception)
{
using (var file = File.AppendText("ErrorLog.txt"))
{
file.WriteLine(DateTime.Now + " : " + exception.Message);
}
}
You can use it in catch block like this
catch(Exception exception)
{
exception.ToLog();
}
See initial information here http://www.csharp-examples.net/catching-unhandled-exceptions/
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception");
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception");
}
The UnhandledException event handles uncaught exceptions thrown from the main UI thread. The ThreadException event handles uncaught exceptions thrown from non-UI threads.
I would replace the MessageBox with some actual logging (log4net or others). This would give you the ability to log out the errors to another server for distributed applications, file system for local users, event logs, options are fairly unlimited if you're willing to put in the time.
Related
After reading this MSDN page, I've created a global exception handler in my .net class library, for logging purposes, which looks like this:
static void OnException(object sender, UnhandledExceptionEventArgs args)
{
Exception ex = (Exception)args.ExceptionObject;
Logging.LogException(ex);
}
But then if I throw new UnauthorizedAccessException() or throw new Exception() from a method, this does not catch it at all.
The MSDN page says:
UnhandledExceptionEventArgs provides access to the exception object
and a flag indicating whether the common language runtime is
terminating. The UnhandledExceptionEventArgs is one of the parameters
passed into UnhandledExceptionEventHandler for the
AppDomain.UnhandledException event
I believe what I'm doing falls under the AppDomain (and not ThreadException)? What am I doing wrong here?
PS. I'm trying to avoid a try-catch block, since apparently it's bad practice. This class library is called from a windows service which runs periodically so I'd rather not let it 'crash' to avoid memory leaks due to unforeseen exceptions and would prefer to monitor the event logs regularly.
You will need to install the exception handler in the current app domain in order for it to fire:
AppDomain.CurrentDomain.UnhandledException += OnException;
Otherwise its just a method declaration that will never be called.
You mention that you are trying to avoid a try catch, but inside your handler, that wouldn't be a bad idea:
static void OnException(object sender, UnhandledExceptionEventArgs args)
{
try
{
Exception ex = (Exception)args.ExceptionObject;
Logging.LogException(ex);
}
catch
{
// do nothing to silently swallow error, or try something else...
}
}
...Because you don't want to explode in your error handler. Either swallow if stability is of primary importance, or try a secondary (more basic) logging method to insure that no exception falls through the cracks.
Normally, swallowing an exception silently is a poor practice, but this is inside an error handling block where failure means crashing an app.
AFAIK, try and finally block are used execute a piece of code that might throw some exception, we also add catch block if we are prepared to handle some type of exception and/or are excepting them, like FileIOException, AccessRight or something. But when I ran this..
private void button1_Click(object sender, EventArgs e)
{
try
{
Environment.FailFast("It failed");
}
finally
{
MessageBox.Show("Done");
}
}
Its breaks with an exception and says
FatalExecutionEngineError was detected
Message: The runtime has encountered a fatal error. The address of the error was at 0x032526f4, on thread 0xd04. The error code is 0x80131623. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.
Now msdn says
Usually, when an unhandled exception ends an application, whether or
not the finally block is run is not important. However, if you have
statements in a finally block that must be run even in that situation,
one solution is to add a catch block to the try-finally statement.
So, I added the catch block, but still it says the same thing.
private void button1_Click(object sender, EventArgs e)
{
try
{
Environment.FailFast("It failed");
}
catch (Exception ex)
{
}
finally
{
MessageBox.Show("Done");
}
}
It failed again with the same error. As for CLR saying the code block in finally always runs (at least when catch is added), it surely is not the case. Reviews/Opinions anyone?
Also here's the snapshot..
This is by design. The purpose of Environment.FailFast is to halt execution immediately. By design it will not run any code in catch or finally blocks.
The documentation says:
This method terminates a process without running any active
try/finally blocks or finalizers.
The FailFast method writes the message string to the Windows
Application event log, creates a dump of your application, and then
terminates the current process. The messa string is also included in
error reporting to Microsoft.
Use the FailFast method instead of the Exit method to terminate your
application if the state of your application is damaged beyond repair,
and executing your application's try/finally blocks and finalizers
will corrupt program resources.
This makes it clear that code in your finally blocks will not run. If there was a way to make code run after Environment.FailFast then that would render Environment.FailFast pretty much useless. Its very existence is predicated on the fact that your code does not execute after you call it.
You point to documentation that states (emphasis mine):
Usually, when an unhandled exception ends an application, whether or not the finally block is run is not important. However, if you have statements in a finally block that must be run even in that situation, one solution is to add a catch block to the try-finally statement.
But those words simply do not apply here. You are assuming that when you call Environment.FailFast, an unhandled exception terminates the application. That is not the case. The application is just terminated on the spot – there is no unhandled exception.
I have developed a project which uses an external dll as FTPServer, I have created the FTP Server on my project like this:
private ClsFTPServer _ClsFTPServer;
_ClsFTPServer = new ClsFTPServer(FTPUserName, FTPPassword, FTPPath);
The Code above creates an instance of FTP server class, the class starts the FTPserver on it's constructor, it works fine independently as a module while the clients send their request correctly, but when an incorrect request comes to FTP server it throws an exception and cause my application to crash.
How can I handle the exception thrown by the external dll to prevent my application from crashing?
I recently answered a similar (ish) question which may prove useful -
Catch completely unexpected error
EDIT. I have to agree with Hans' comment above - might be an idea to find another FTP server.
Just for completeness, here's the appdomain/thread exception setup from - http://msdn.microsoft.com/en-GB/library/system.windows.forms.application.threadexception.aspx
Application.ThreadException += new ThreadExceptionEventHandler (ErrorHandlerForm.Form1_UIThreadException);
// Set the unhandled exception mode to force all Windows Forms errors to go through
// our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
// Add the event handler for handling non-UI thread exceptions to the event.
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
In case of using external unmanaged\unsafe code, .NET (above .net 4) by default cannot handle Memory Access Violation exceptions that happens inside of dll code.
in order to catch these kind of exceptions, there is three things to do. I did them and it worked for me:
Add these Attributes to the method that exception occurred inside of it :
(the method that calls the method of the unmanaged code.)
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
Add this tag to App.Config file below runtime tag :
<runtime>
<legacyCorruptedStateExceptionsPolicy enabled="true"/>
<!-- other tags -->
</runtime>
Catch these kind of exception by using System.AccessViolationException exception type :
try{
//Method call that cause Memory Access violation Exeption
}
catch (System.AccessViolationException exception)
{
//Handle the exception here
}
What i said is just the cure for these type of exception. for more information about this exception's ego and how this approach works, see System.AccessViolationException
You've probably already tried this, but just in case, have you tried wrapping it in a try catch?
try
{
_ClsFTPServer = new ClsFTPServer(FTPUserName, FTPPassword, FTPPath);
...
}
catch(Exception e)
{
...
}
By putting a try...catch block around every call into the object and its methods.
Something like:
try
{
// use the DLL in some way
}
catch (Exception e)
{
// Handle the exception, maybe display a warning, log an event, etc.)
}
Also note that while running under Visual Studio, if you go to the "Debug" menu and select "Exceptions..." it will allow the debugger to break on ALL exceptions if you start your program under the debugger, and not just unhandled exceptions. Just click the 'Thrown' checkbox next to "Common Language Runtime Exceptions".
I have an app, and after about 20 minutes of idle time the program just crashes. ("Windows has encountered an error and needs to close...")
I have no idea why this is happening. What is the best way to go about debugging something like this?
Generally crashes in .Net applications are caused by an unhandled exception - i.e. an exception in a thread in that application that was not caught in a try-catch block of some sort:
try
{
// Some code that may throw an exception
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
A good first place to check for information about this exception is the application event log, often however you will find that the .Net framework posts only minimal information about the crash - if this is the case then you need to catch and handle the exception yourself, recording enough information to allow you to diagnose the error.
Typically there are two way that you might do this:
1. Ensure that the code for each thread of your application is contained in a try-catch block.
This is the easiest method - unless your application has multiple user threads (you will know if it has), this simply requires that you place a try-catch block around the entry point of your application, for example in a Windows Forms application:
// Probably found somewhere in Program.cs
[STAThread]
static void Main()
{
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
If you are working on a console application then you will need to use something other than MessageBox (see the first example).
If you spawn multiple threads then the entry point method for each thread should also catch all exceptions in a similar way.
2. Handle the UnhandledException event of the current App Domain
This event will be fired whenever any thread throws an unhandled exception in the current App Domain. Generally speaking it is best to use the first method instead, however this event is still useful in some situations.
Example:
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
// The rest of your application
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine(e.ExceptionObject.ToString());
}
Of course it is worth pointing out that the error still might not be caught by either of the above two methods (which is possible if the error is caused by a native module loaded in the same process), however this should probably do the trick.
Finally - Good luck!
If I have a method that I know could potentially recurse infinitely, but I can't reliably predict what conditions/parameters would cause it, what's a good way in C# of doing this:
try
{
PotentiallyInfiniteRecursiveMethod();
}
catch (StackOverflowException)
{
// Handle gracefully.
}
Obviously in the main thread you can't do this, but I've been told a few times it's possible to do it using threads or AppDomain's, but I've never seen a working example. Anybody know how this is done reliably?
You can't. From MSDN
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. Consequently,
users are advised to write their code
to detect and prevent a stack
overflow. For example, if your
application depends on recursion, use
a counter or a state condition to
terminate the recursive loop. Note
that an application that hosts the
common language runtime (CLR) can
specify that the CLR unload the
application domain where the stack
overflow exception occurs and let the
corresponding process continue. For
more information, see
ICLRPolicyManager Interface and
Hosting Overview.
There is no way to catch StackOverflowException, but you can do something with unhandled exception:
static void Main()
{
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}
static void CurrentDomain_UnhandledException
(object sender, UnhandledExceptionEventArgs e)
{
try
{
Exception ex = (Exception)e.ExceptionObject;
MessageBox.Show("Whoops! Please contact the developers with the following"
+ " information:\n\n" + ex.Message + ex.StackTrace,
"Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
finally
{
Application.Exit();
}
}