Passing exceptions through class to main window - c#

So i am making a program for school, the section i am working on currently i have an if statement set up and when the if is false it will throw and exception, I have a catch set up in the main window but the exception is never caught just thrown, which stops the program. I understand i need the catch in the main window because that is the only location i can have a messagebox.show. But how do i pass the exception throughout multiple classes?

Use something like this:
AppDomain.CurrentDomain.UnhandledException
+= new UnhandledExceptionEventHandler(ErrorHandler.HandleException);

Related

How to try/catch all exceptions

I'm completing a UWP app started by someone else. The app crashes frequently and I always end up in App.g.i.cs at
if (global::System.Diagnostics.Debugger.IsAttached)
global::System.Diagnostics.Debugger.Break();
where I then have to say "no, don't start the debugger" and close 2 windows.
Is there somewhere I could put a big try/catch so that I don't have to restart the app each time this happen? I can't find anything in AppShell or App.
Or do I have to put a try/catch in every single event handler?
If you want to avoid starting the new debugger and restarting the app each time when encountering unhandled exceptions, you can use Application.UnhandledException event and set the Handled property of the event arguments to true like following:
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
this.UnhandledException += (sender, e) =>
{
e.Handled = true;
System.Diagnostics.Debug.WriteLine(e.Exception);
};
}
The UnhandledException event is used to notify the app about exceptions encountered by the XAML framework or by the Windows Runtime in general that have not been handled by app code.
Normally after the UnhandledException event is fired, the Windows Runtime terminates the app because the exception was unhandled. The app code has some control over this: if the UnhandledException event handler sets the Handled property of the event arguments to true, then in most cases the app will not be terminated.
For more info, please see Remarks of Application.UnhandledException event and the blog: Strategies for Handling Errors in your Windows Store Apps.
As far as i know most you cant do what you are trying to do (big try catch block) and for all intents and purposes you shouldn't even consider that possibility.
First try to determine why the app is crashing, on what page, is it when you try to something specific, the same thing everytime and then you can try catch some of the methods on that particular page and determine what's causing the crash
If you want to treat the cause rather than the symptoms, you should enable first-chance exceptions in the debugger settings. Then the debugger should break at the source of the exception, rather than in the global handler. You can then address the root cause of the problems directly.
Shipping an app that has the global handler blindly set every exception as "handled" even when you don't know why it's failing is not a good solution.
You can try/catch in your main app to catch all exceptions. Shown is an example using Xamarin Forms DisplayAlert:
try
{
//throw new Exception("gone and done it");
MyMainProgram();
}
catch (Exception ex)
{
await DisplayAlert("Whoops!", ex.Message, "ok");
throw ex;
}
You can test this by uncommenting the "throw new Exception". Execution stops with an alert you must answer, then continues by throwing the exception to prevent executing corrupted code.

Global level error handling in C# windows application

I am trying to implement global level error handling in my windows application
I have the button click event for the form which creates some error
label1.Text =
class1.Calculate(Convert.ToSingle(textBox1.Text), Convert.ToSingle(textBox2.Text))
.ToString(CultureInfo.InvariantCulture);
MessageBox.Show("That was really Close");
now I want the control to go to message box, the unhandled error are being handled in the main function as
private static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
Application.Run(new Form1());
}
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
if (e.Exception.InnerException != null)
MessageBox.Show(e.Exception.InnerException.Message.ToString());
else MessageBox.Show(e.Exception.ToString());
}
This code sample does handles the exception but I want the control back to the button Click, that is The MessageBox.Show("That was really Close"); should get called after exception handling
If you don't want the method to stop on an exception then you need to handle the exception at that point. You could have the catch call some kind of global error handling method but you will need a try catch in that method.
Global level exception handling is for exceptions that you can't deal with immediately and need to catch before the program dies, usually for logging and such like.
Global level exception handling is not a substitute for handling exceptions at the correct place. If you expect code to throw an exception and it is one you can deal with then you should put a try/catch at that point of the code. In the example above you say you want to carry on running the method so clearly the error is not a fatal one so you should deal with it in the normal way.
Often though it should be noted that exceptions that you can handle are ones that can be avoided. For example checking what you pass to a method before passing it. The ones that can't be removed entirely are usually ones to do with external resources (eg reading files). I'm sure there are a lot of other exceptions but as somebody wise once said "Exceptions are for exceptional circumstances". If you can foresee them you should try to avoid them.
In this case I assume the exception is related to invalid input in your text boxes. In this case you should use Single.TryParse to verify the input before passing it on to your method. If either of the values fails to parse you can then let the user know that properly.

Catching debugging error message in one single place

I am working on a big application that has a lot of levels of hierarchy, and I am getting to a point where I am going nuts about calling logging messages and forgetting about them.
From time to time while testing I run into exceptions. Now I am forwarding error messages to my main form through interfaces and other ways.
Is there a way to make the application in a case of an exception to always trigger a single method in the main form.
I mean, now I catch the exception and forward it through the interfaces. I would like to be able to ignore this and every time an exception happens, execute automaticly one method in the main form
If you allow the exceptions to bubble up through the application you can use AppDomain.UnhandledException. You should allow any exception which you cannot meaningfully handle to bubble up anyway.
Something like this should do the trick:
class Program
{
public static void Main()
{
form = new MainForm();
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(form.OnUnhandledException);
Application.Run(form);
}
}

Catching exception in Main() method

Consider the following simple application: a windows form created by a "new C# windows application" sequence in VS that was modified in a following way:
public static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
try
{
Application.Run(new Form1());
}
catch (Exception ex)
{
MessageBox.Show("An unexpected exception was caught.");
}
}
Form1.cs contains the following modifications:
private void Form1_Load(object sender, EventArgs e)
{
throw new Exception("Error");
}
If I press F5 in IDE, then, as I expect, I see a message box saying that exception was caught and the application quits.
If I go to Debug(or Release)/bin and launch the executable, I see the standard "Unhandled exception" window, meaning that my exception handler doesn't work.
Obviously, that has something to do with exception being thrown from a different thread that Application.Run is called from. But the question remains - why the behavior differs depending on whether the application has been run from IDE or from command line?
What is the best practice to ensure that no exceptions remain unhandled in the application?
Normally Application.ThreadException will handle the exception in the Load event. You'll get the ThreadExceptionDialog that offers the Quit and Continue options.
But not when a debugger is attached. The catch clause in the message loop that displays the dialog is intentionally disabled in that case. That's necessary because it would be very difficult to trouble-shoot exceptions if that dialog pops up when you debug a program. Which this catcher no longer active, your catch clause in the Main() method now gets a shot at the exception.
You can make it consistent by using Application.SetUnhandledExceptionMode() in the Main() method. You shouldn't, exceptions really are hard to debug if you do this. If you want to customize exception handling for the UI thread then you should register your own Application.ThreadException handler:
if (!System.Diagnostics.Debugger.IsAttached)
Application.ThreadException += myThreadException;
Trapping unhandled exceptions in worker threads requires a AppDomain.UnhandledException handler. They are not recoverable.
Also beware of a bug in 64-bit Windows, exceptions in the Load event are swallowed without diagnostic when a debugger is attached. Force AnyCPU mode to avoid that trap.
In addition to catching any exceptions thrown inside the Main method you must also handle AppDomain.CurrentDomain.UnhandledException and Application.ThreadException.
Not sure why the behavior differs with and without a debugger attached though.

How do I 'globally' catch exceptions thrown in object instances

I am currently writing a winforms application (C#).
I am making use of the Enterprise Library Exception Handling Block, following a fairly standard approach from what I can see. IE : In the Main method of Program.cs I have wired up event handler to Application.ThreadException event etc.
This approach works well and handles the applications exceptional circumstances.
In one of my business objects I throw various exceptions in the Set accessor of one of the objects properties
set {
if (value > MaximumTrim)
throw new CustomExceptions.InvalidTrimValue("The value of the minimum trim...");
if (!availableSubMasterWidthSatisfiesAllPatterns(value))
throw new CustomExceptions.InvalidTrimValue("Another message...");
_minimumTrim = value;
}
My logic for this approach (without turning this into a 'when to throw exceptions' discussion) is simply that the business objects are responsible for checking business rule constraints and throwing an exception that can bubble up and be caught as required. It should be noted that in the UI of my application I do explictly check the values that the public property is being set to (and take action there displaying friendly dialog etc) but with throwing the exception I am also covering the situation where my business object may not be used by a UI eg : the Property is being set by another business object for example. Anyway I think you all get the idea.
My issue is that these exceptions are not being caught by the handler wired up to Application.ThreadException and I don't understand why.
From other reading I have done the Application.ThreadException event and it handler "... catches any exception that occurs on the main GUI thread". Are the exceptions being raised in my business object not in this thread? I have not created any new threads.
I can get the approach to work if I update the code as follows, explicity calling the event handler that is wired to Application.ThreadException. This is the approach outlined in Enterprise Library samples. However this approach requires me to wrap any exceptions thrown in a try catch, something I was trying to avoid by using a 'global' handler to start with.
try
{
if (value > MaximumTrim)
throw new CustomExceptions.InvalidTrimValue("The value of the minimum...");
if (!availableSubMasterWidthSatisfiesAllPatterns(value))
throw new CustomExceptions.InvalidTrimValue("Another message");
_minimumTrim = value;
}
catch (Exception ex)
{
Program.ThreadExceptionHandler.ProcessUnhandledException(ex);
}
I have also investigated using wiring a handler up to AppDomain.UnhandledException event but this does not catch the exceptions either.
I would be good if someone could explain to me why my exceptions are not being caught by my global exception handler in the first code sample. Is there another approach I am missing or am I stuck with wrapping code in try catch, shown above, as required?
As a thought, try adding (fairly early on - i.e. at the start of Main):
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
That said - it seems to work fine for me with or without...
According to MSDN, Application.ThreadException will only be fired if the exception isn't handled. Maybe there is a catch somewhere up the callstack that is handling the exception?
Another option would be to try using AppDomain.UnhandledException instead. It is the same as Application.ThreadException, except it works for all exceptions in the same AppDomain.
If you try to use use
Application.ThreadException
or
AppDomain.CurrentDomain.UnhandledException
the Debugger will catch the exception!
To test these methods you have to start the appication without a debugger.

Categories