Exception Handling in SCSF - c#

I have a SCSF application i am trying to handle most of the exceptions using
Application.ThreadException += new ThreadExceptionEventHandler(new ThreadExceptionHandler().ApplicationThreadException);
The event handler :-
public class ThreadExceptionHandler
{
public void ApplicationThreadException(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message, "An exception occurred:", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Works fine . I can catch all the application exceptions in this block.
But the problem is after handling the exception the code again goes and executes the same exception generating code again. This happens till the time I get a windows message windows to send the error info to microsoft.
Could any one please help in telling me where I might be going wrong.
Thanks in Advance
Vikram
Note :- Currently i am throwing
New Exception("Test Exception"); from a button event. I am doing this to provide event handling in my application.

You have to set
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
See this MSDN page for example code
But note that this kind of catch-all exception handling is not a good replacement for exception handling inside your logic. It is a good backup, but the best thing to do in a global handler is to log the information and exit. Your app could be in an unsafe/undefined state.

After some banging my head against the code I found that the problem was due to the fact that my SCSF solution had a winforms Shell and on that shell there were WPF usercontrols.
When the exception where generated on these WPF usercontrol (mostly the case) they are not caught by
Application.ThreadException coz Application class for WPF is different than that for Winforms.
In WPF application one need to handle Application.DispacherUnhandledException event.
Just my little finding ...

you would be surprised by just handling the Application.DispatcherUnhandledException. I have worked with SCSF which had WPF user controls. Read through this post . http://social.msdn.microsoft.com/forums/en-US/wpf/thread/c57cac13-f960-49a1-94b5-a3fd316ac4bc/ i would recommend handling AppDomain.UnhandledException too.

Related

How can I handle the exception which throws on an external dll?

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".

Globally handle WPF exceptions without a WPF Application object

WPF provides a very convenient way to handle unexpected exceptions: I can just attach a handler to the Application.DispatcherUnhandledException event and all unhandled exceptions go this way:
Application.Current.DispatcherUnhandledException += (sender, e) => {
// Show message, log exception, etc.
};
This works great for WPF application projects. Now, I have a library with WPF windows, which is called from a non-WPF application (it's a legacy VBA app, and the WPF library is made accessible via COM interop).
So, the thing is: I can create, open and show WPF windows (this works fine), but I don't have an Application instance. Application.Current is null. I use the WPF classes, but I operate them outside the WPF application framework.
Currently, the only drawback of this solution is that exceptions in WPF window event handler code are silently swallowed:
void Button_click(sender as object, e as RoutedEventArgs) {
...
// some exception occurs here, but nobody hears her scream
...
}
I don't like that. I'd like to log them and show error messages.
My question: Is there a way to globally catch unhandled exceptions in this scenario or do I have to add a gerneric try-catch-log block to every WPF window event handler code I write?
What I have tried:
Attaching to AppDomain.CurrentDomain.UnhandledException. Doesn't work. Exceptions don't get there.
Reading the relevant parts of MSDN regarding WPF and Win32 interop (Ref 1, Ref 2, Ref 3). Exceptions are not mentioned there.
Attach to the Dispatcher instead:
Dispatcher.CurrentDispatcher.DispatcherUnhandledException += (sender, e) => {
// Show message, log exception, etc.
};
If no dispatcher exists yet, accessing CurrentDispatcher automatically creates a singleton Dispatcher which will also be used by the WPF windows.

Getting exception that caused program to crash without being in debug mode

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.

Getting Windows error reporting dialog

In my C# app, even I handle exception :
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
and then in handler showing dialog box and doing Application.Exit
still getting windows error reporting dialog with Send, Don't Send...
How to prevent windows error reporting dialog from popping up?
In fact if the exception is thrown from main form constructor then the program ends up with Windows error report dlg. Otherwise if from some other location of UI thread, then as expected.
You'll need to terminate the app yourself. This will do it:
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
var ex = e.ExceptionObject as Exception;
MessageBox.Show(ex.ToString());
if (!System.Diagnostics.Debugger.IsAttached)
Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(ex));
}
The dialog that presents the choice to send or not send an error report to Microsoft is beyond exceptions. This might happen if you use unsafe{} blocks or you use p/invoke's which perform some illegal operation.
I think you should not be fighting the symptoms of your problem. The unhandled exceptions should not happen in the first place.
Do you have any clues on what is causing them?

Easy way to catch all unhandled exceptions in C#.NET

I have a website built in C#.NET that tends to produce a fairly steady stream of SQL timeouts from various user controls and I want to easily pop some code in to catch all unhandled exceptions and send them to something that can log them and display a friendly message to the user.
How do I, through minimal effort, catch all unhandled exceptions?
this question seems to say it's impossible, but that doesn't make sense to me (and it's about .NET 1.1 in windows apps):
All unhandled exceptions finally passed through Application_Error in global.asax. So, to give general exception message or do logging operations, see Application_Error.
If you need to catch exeptions in all threads the best aproach is to implement UnhandledExceptionModule and add it to you application look here
for an example
Use the Application_Error method in your Global.asax file. Inside your Application_Error method implementation call Server.GetLastError(), log the details of the exception returned by Server.GetLastError() however you wish.
e.g.
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
log4net.ILog log = log4net.LogManager.GetLogger(typeof(object));
using (log4net.NDC.Push(this.User.Identity.Name))
{
log.Fatal("Unhandled Exception", Server.GetLastError());
}
}
Don't pay too much attention to the log4net stuff, Server.GetLastError() is the most useful bit, log the details however you prefer.
The ELMAH project sounds worth a try, its list of features include:
ELMAH (Error Logging Modules and
Handlers) is an application-wide error
logging facility that is completely
pluggable. It can be dynamically added
to a running ASP.NET web application,
or even all ASP.NET web applications
on a machine, without any need for
re-compilation or re-deployment.
Logging of nearly all unhandled exceptions.
A web page to remotely view the entire log of recoded exceptions.
A web page to remotely view the full details of any one logged
exception.
In many cases, you can review the original yellow screen of death that
ASP.NET generated for a given
exception, even with customErrors mode
turned off.
An e-mail notification of each error at the time it occurs.
An RSS feed of the last 15 errors from the log.
A number of backing storage implementations for the log
More on using ELMAH from dotnetslackers
You can subscribe to the AppDomain.CurrentDomain.UnhandledException event.
It's probably important to note that you are not supposed to catch unhandled exceptions. If you are having SQL timeout issues, you should specifically catch those.
Do you mean handling it in all threads, including ones created by third-party code? Within "known" threads just catch Exception at the top of the stack.
I'd recommend looking at log4net and seeing if that's suitable for the logging part of the question.
If using .net 2.0 framework, I use the built in Health Monitoring services. There's a nice article describing this method here: https://web.archive.org/web/20210305134220/https://aspnet.4guysfromrolla.com/articles/031407-1.aspx
If you're stuck with the 1.0 framework, I would use ELMAH:
http://msdn.microsoft.com/en-us/library/aa479332.aspx
hope this helps
There are 2 parts to this problem handling & identifying.
Identifying
This is what you do when the exception is finally caught, not necessarily where it is thrown. So the exception at that stage must have enough context information for you to idenitfy what the problem was
Handling
For handling, you can
a) add a HttpModeule. See
http://www.eggheadcafe.com/articles/20060305.asp
I would suggest this approach only when there is absolutely no context informaatn available and there might be issuus wiih IIS/aspnet, In short for catastrophic situations
b) Create a abstract class called AbstractBasePage which derives from Page class and have all your codebehind classes derive from AbstractBasePage
The AbstractBasePage can implement that Page.Error delegate so that all exceptions which percolate up through the n-tier architecture can be caught here(and possibly logged)
I would suggest this cause for the kind of exceptions you are talking about (SQlException) there is enough context information for you to identify that it was a timeout and take possible action. This action might include redirecting user to a custom error page with appropriate message for each different kind of exception (Sql, webservice, async call timeouts etc).
Thanks
RVZ
One short answer is to use (Anonymous) delegate methods with common handling code when the delegate is invoked.
Background: If you have targeted the weak points, or have some boilerplate error handling code you need to universally apply to a particular class of problem, and you don't want to write the same try..catch for every invocation location, (such as updating a specific control on every page, etc).
Case study: A pain point is web forms and saving data to the database. We have a control that displays the saved status to the user, and we wanted to have common error handling code as well as common display without copy-pasting-reuse in every page. Also, each page did it's own thing in it's own way, so the only really common part of the code was the error handling and display.
Now, before being slammed, this is no replacement for a data-access layer and data access code. That's all still assumed to exist, good n-tier separation, etc. This code is UI-layer specific to allow us to write clean UI code and not repeat ourselves. We're big believers in not quashing exceptions, but certain exceptions shouldn't necessitate the user getting a generic error page and losing their work. There will be sql timeouts, servers go down, deadlocks, etc.
A Solution: The way we did it was to pass an anonymous delegate to a method on a custom control and essentially inject the try block using anonymous delegates.
// normal form code.
private void Save()
{
// you can do stuff before and after. normal scoping rules apply
saveControl.InvokeSave(
delegate
{
// everywhere the save control is used, this code is different
// but the class of errors and the stage we are catching them at
// is the same
DataContext.SomeStoredProcedure();
DataContext.SomeOtherStoredProcedure();
DataContext.SubmitChanges();
});
}
The SaveControl itself has the method like:
public delegate void SaveControlDelegate();
public void InvokeSave(SaveControlDelegate saveControlDelegate)
{
// I've changed the code from our code.
// You'll have to make up your own logic.
// this just gives an idea of common handling.
retryButton.Visible = false;
try
{
saveControlDelegate.Invoke();
}
catch (SqlTimeoutException ex)
{
// perform other logic here.
statusLabel.Text = "The server took too long to respond.";
retryButton.Visible = true;
LogSqlTimeoutOnSave(ex);
}
// catch other exceptions as necessary. i.e.
// detect deadlocks
catch (Exception ex)
{
statusLabel.Text = "An unknown Error occurred";
LogGenericExceptionOnSave(ex);
}
SetSavedStatus();
}
There are other ways to achieve this (e.g. common base class, intefaces), but in our case this had the best fit.
This isn't a replacement to a great tool such as Elmah for logging all unhandled exceptions. This is a targeted approach to handling certain exceptions in a standard manner.
Timeout errors typically occur if you are not forcefully closing your sqlconnections.
so if you had a
try {
conn.Open();
cmd.ExecuteReader();
conn.Close();
} catch (SqlException ex) {
//do whatever
}
If anything goes wrong with that ExecuteReader your connection will not be closed. Always add a finally block.
try {
conn.Open();
cmd.ExecuteReader();
conn.Close();
} catch (SqlException ex) {
//do whatever
} finally {
if(conn.State != ConnectionState.Closed)
conn.Close();
}
This is old question, but the best method (for me) is not listed here. So here we are:
ExceptionFilterAttribute is nice and easy solution for me. Source: http://weblogs.asp.net/fredriknormen/asp-net-web-api-exception-handling.
public class ExceptionHandlingAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
var exception = context.Exception;
if(exception is SqlTimeoutException)
{
//do some handling for this type of exception
}
}
}
And attach it to f.e. HomeController:
[ExceptionHandling]
public class HomeController: Controller
{
}

Categories

Resources