I have been trying to log this exception for days but cant figure it out. So I thought I post it here with the hope that someone could help. I have also posted some of my code that I'm currently using to catch unhandled exceptions but the exception never showed up in the log file.
I would appreciate if someone could help me.
Problem Event Name: APPCRASH
Application Name: Myapp.exe
Application Version: 1.0.0.0
Application Timestamp: 52e9aab8
Fault Module Name: clr.dll
Fault Module Version: 4.0.30319.18052
Fault Module Timestamp: 5173c26b
Exception Code: c00000fd
Exception Offset: 00372b52
OS Version: 6.1.7601.2.1.0.272.7
Locale ID: 1033
Additional Information 1: 5cff
Additional Information 2: 5cfff2c5825852a6f100872ec6f038a2
Additional Information 3: a2a3
Additional Information 4: a2a3734c473189c5efabc88b5081d05a
public MainWindow()
{
Application.Current.DispatcherUnhandledException += CurrentOnDispatcherUnhandledException;
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
Dispatcher.UnhandledException += DispatcherOnUnhandledException;
InitializeComponent();
}
private void DispatcherOnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.Exception;
using (StreamWriter writer = File.AppendText("ExceptionsLog.txt"))
{
DateTime time = DateTime.Now;
writer.WriteLine("Time {0} Exception: {1}", time, e);
writer.Flush();
}
args.Handled = true;
MessageBox.Show(e.ToString());
}
private void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.ExceptionObject;
using (StreamWriter writer = File.AppendText("ExceptionsLog.txt"))
{
DateTime time = DateTime.Now;
writer.WriteLine("Time {0} Exception: {1} Runtime termination: {2}", time, e.Message, args.IsTerminating);
writer.Flush();
}
MessageBox.Show(e.ToString());
}
private void CurrentOnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.Exception;
using (StreamWriter writer = File.AppendText("ExceptionsLog.txt"))
{
DateTime time = DateTime.Now;
writer.WriteLine("Time {0} Exception: {1}", time, e);
writer.Flush();
}
args.Handled = true;
MessageBox.Show(e.ToString());
}
For handling unhandled exceptions, please create a method like this
protected TResult LogFailedOperations<TResult>(Func<TResult> action)
{
try
{
return action();
}
catch (Exception ex)
{
// Logic for logging from ex.Message
}
}
Also, when you perform any method, just enclose that method around this LogFailedOperations method like these examples -
private void MyButton_Click(object sender, RoutedEventArgs e)
{
var result = LogFailedOperations(() => { /* Your logic for button click */ });
}
private void LoadDataToView()
{
var result = LogFailedOperations(() => { /* Your logic for laoding data */ });
}
private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
var result = LogFailedOperations(() => { /* Your logic for slider changed event */ });
}
Related
This question has been answered a thousand times but although I've tried everything, I can't seem to get my Global Exception Handler to work.
I'm using a windows form with several async methods. All my async methods are wrapped in try catch blocks and handled accordingly. I also have every block of code where I expect an exception wrapped in a try catchblock.
I'm interested in using a global exception handler to catch exceptions that I'm not expecting so that I can log them and let the user know there has been an exception before safely closing down the program.
In Main() I have the following:
[STAThread]
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
static void Main()
{
crashLogInit = InitLogExceptions(); // sets global exception handlers and returns true if successful.
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MainWindow = new MainWindow(); // My window
LoadSaveManager.Init(); // initiates all relavent components for saving and loading data.
if (isLoaded() && crashLogInit) // Loads data and checks it is successful, also checks global exception handlers are set.
{
RunProgram(); //Method which does Application.Run(MainWindow);
}
else
{
MessageBox.Show(Form.ActiveForm, "Error while starting application!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
CloseResources();
}
}
In the InitLogExceptions() I have the following:
private static bool InitLogExceptions()
{
try
{
crashlogPath = Path.Combine(Directory.GetCurrentDirectory(), crashlogName);
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
return true;
}
catch { return false; }
}
In MainWindow() I have a button which fires a clicked event which throws an ArgumentNullException which is getting caught by the debbugers own exception handler but isnt getting caught by any of mine nor is it getting logged.
Below is the code for my exception handlers:
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
ShowException(sender, e.Exception, true);
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
ShowException(sender, e.ExceptionObject as Exception, true);
}
public static void ApplicationHandler(object sender, Exception e)
{
if (!crashLogInit) { InitLogExceptions(); }
ShowException(sender, e, false);
}
public static void ApplicationHandler(object sender, Exception e, bool forceClose)
{
if (!crashLogInit) { InitLogExceptions(); }
ShowException(sender, e, forceClose);
}
private static bool WriteToLog(object sender, Exception exception)
{
try
{
DateTime dateTime = DateTime.Now;
StreamWriter writer = File.AppendText(crashlogPath);
string date = dateTime.ToString("yyyy-MM-dd # HH:mm:ss");
writer.WriteLine(date + ":");
writer.WriteLine();
writer.WriteLine();
writer.Write($" SENDER: {sender.GetType().ToString()} EXCEPTION MESSAGE: {exception.Message}");
writer.WriteLine(exception.Source == null ? "" : $"SOURCE: {exception.Source}");
writer.WriteLine();
writer.WriteLine(exception.StackTrace == null ? exception.InnerException.StackTrace : exception.StackTrace);
if (exception.GetType().IsSubclassOf(typeof(AppExceptions)))
{
writer.WriteLine();
writer.WriteLine($"ORIGINAL MESSAGE: {exception.InnerException.Message} ORIGINAL SOURCE: {exception.InnerException.Source}");
}
writer.WriteLine();
writer.WriteLine();
writer.Close();
return true;
}
catch (Exception)
{
return false;
}
}
private static void ShowException(object sender, Exception e, bool forceClose)
{
StringBuilder output = new StringBuilder();
if (WriteToLog(sender, e))
{
output.AppendLine($"Copied to Crashlog! Location of Crashlog file: {crashlogPath}");
output.AppendLine();
output.AppendLine("Send Crashlog to developer!");
}
else
{
output.AppendLine("Could not copy to Crashlog!");
}
output.AppendLine();
output.AppendLine(forceClose ? "Application will now close!" : "Application will now continue at user's own risk!");
MessageBox.Show(Form.ActiveForm, output.ToString(), e.Message.ToUpper() + "!", MessageBoxButtons.OK, MessageBoxIcon.Error);
if (forceClose)
{
Environment.FailFast(e.Message, e);
}
}
Exceptions else where are working and getting logged except this simple thrown exception on a button clicked. What am I doing wrong?
I want to catch all unhandled exceptions in my application. so I used this code to catch all the unhandled exceptions:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
SaveEx(e.Exception);
Application.Exit();
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
SaveEx((Exception)e.ExceptionObject);
Application.Exit();
}
static void SaveEx(Exception ex)
{
bool exists = System.IO.Directory.Exists(Path.GetDirectoryName(#"C:\AppLogs\"));
if (!exists)
System.IO.Directory.CreateDirectory(Path.GetDirectoryName(#"C:\AppLogs\"));
String filePath = #"C:\AppLogs\" + DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".txt";
String log = "===========Start=============\r\n";
log += "Error Message: " + ex.Message + "\r\n";
log += "Stack Trace: " + ex.StackTrace + "\r\n";
log += "===========End=============";
System.IO.File.WriteAllText(filePath, log);
}
}
I tried to raise these exceptions with a divide in 0:
on main thread it's work perfect:
int t = 0;
int r = 5 / t;
But when i try to do it inside a Thread:
Thread thread = new Thread(delegate()
{
int t = 0;
int r = 5 / t;
});
thread.Start();
The CurrentDomain_UnhandledException function got called but it keeps calling the int r = 5 / t; row in my code so I have a loop of exceptions. Any idea what can be the problem? the thread is called only once.
You need to change Application UnhandledExceptionMode
to UnhandledExceptionMode.CatchException to make things works correctly. Microsoft already wrote a very good article about it here.
I tried to simulate your work. Everything worked well, take a look on my example.
[STAThread]
static void Main()
{
// 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 UI thread exceptions to the event.
Application.ThreadException += Application_ThreadException;
// Add the event handler for handling non-UI thread exceptions to the event.
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message, "Application_ThreadException");
Application.Exit();
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var exception = e.ExceptionObject as Exception;
MessageBox.Show(exception.Message, "CurrentDomain_UnhandledException");
Application.Exit();
}
So, if we raise an exception inside a thread like below:
private void button1_Click(object sender, EventArgs e)
{
var thread = new Thread(delegate () {
throw new DivideByZeroException();
});
thread.Start();
}
button1_Click is fired.
thread get started and raises a DividedByZeroException.
CurrentDomain_UnhandledException catches the exception, shows the message and closes the app
I'm developing one WPF application, in which I've to handle Exception globally.
For that I've refer MSDN document.
And accordingly my code on my main window:
private void TestMethod()
{
string s = null;
try
{
s.Trim();
}
catch (Exception ex)
{
MessageBox.Show("A handled exception just occurred: " + ex.Message, "RestartApplication", MessageBoxButton.OK, MessageBoxImage.Warning);
}
s.Trim();
}
In my App.xaml.cs
public App() : base()
{
this.Dispatcher.UnhandledException += Application_DispatcherUnhandledException;
}
private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show("An unhandled exception just occurred: " + e.Exception.Message, "Exception Sample", MessageBoxButton.OK, MessageBoxImage.Warning);
e.Handled = true;
}
Here i expecting two MessageBoxfor an exception. and seems like Application_DispatcherUnhandledException not called.
But VS gives an error on second s.Trim();
How can i handle an error and show message box from App.xaml.cs?
I've refer many links of SO like: dispatcherunhandledexception-does-not-seem-to-work
globally-catch-exceptions-in-a-wpf-application
Update : Real time application code, were second message box not displaying :
private void ListProcesses()
{
string s = null;
Process[] localByName = Process.GetProcessesByName("notepad++");
DateTime test = new DateTime();
try
{
s.Trim();
foreach (Process p in localByName)
{
this.Dispatcher.Invoke(() =>
{
if (storevalue != p.MainWindowTitle && !String.IsNullOrEmpty(p.MainWindowTitle))
{
aTimer.Stop();
this.Visibility = Visibility.Visible;
this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
this.Topmost = true;
this.WindowState = System.Windows.WindowState.Maximized;
this.ResizeMode = System.Windows.ResizeMode.NoResize;
storevalue = p.MainWindowTitle;
}
});
}
}
catch (Exception ex)
{
aTimer.Stop();
MessageBoxResult result = MessageBox.Show("A handled exception just occurred: " + ex.Message, "RestartApplication", MessageBoxButton.OK, MessageBoxImage.Warning);
}
s.Trim();
}
Erm..I think I know what is happening to you. The Dispatcher.UnhandledException event only works when the app is running, not when you run it from the Visual Studio. Try to run it from the Debug folder for example, and i think you'll see the expected behaviour.
When you run your app from Visual Studio, VS itself is handling the exception so it would never be unhandled, thus never firing the Dispatcher.UnhandledException event.
EDIT
Ok, after studying your code, i guess your ListProcesses method is running in a Timer. Timers does not pass the exceptions to the calling thread, so it would never work. If you are using System.Timers.Timer it will silently swallow exceptions and if you use System.Threading.Timer will terminate the program.
So in that case, you'll need to take care of the Exceptions yourself, sorry :)
Remove your try / catch blocks, and run "Start Without Debugging (Ctrl+F5)" .
Application.DispatcherUnhandledException Event
is fired only by unhandled exceptions.
This is what I did :
public partial class Window12 : Window
{
public Window12()
{
InitializeComponent();
string id = null;
id.Trim();
}
}
App.xaml.cs
public partial class App : Application
{
public App()
{
this.DispatcherUnhandledException += App_DispatcherUnhandledException;
}
void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show("Unhandled exception occured > " + e.Exception.ToString());
}
}
I'm trying to learn how to log errors in WPF and keep the app running. I've found that DispatcherUnhandledException won't capture errors inside a thread, so I'm also using currentDomain.UnhandledException
In the example below my error is being captured and logged but the application still crashes. How do I log the error but prevent the app from crashing?
Problem signature:
Problem Event Name: CLR20r3
Problem Signature 01: test.exe
Problem Signature 02: 1.0.0.0
Problem Signature 03: 5292262f
Problem Signature 04: test
Problem Signature 05: 1.0.0.0
Problem Signature 06: 5292262f
Problem Signature 07: 24b
Problem Signature 08: 6
Problem Signature 09: System.DivideByZeroException
App.xaml.cs:
protected override void OnStartup(StartupEventArgs e)
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
}
static void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception theException = (Exception)args.ExceptionObject;
string theErrorPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\GeneratorTestbedError23.txt";
using (System.IO.TextWriter theTextWriter = new System.IO.StreamWriter(theErrorPath, true))
{
DateTime theNow = DateTime.Now;
theTextWriter.WriteLine("The error time: " + theNow.ToShortDateString() + " " +
theNow.ToShortTimeString());
while (theException != null)
{
theTextWriter.WriteLine("Exception: " + theException.ToString());
theException = theException.InnerException;
}
}
}
private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
Exception theException = e.Exception;
string theErrorPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) +
"\\GeneratorTestbedError.txt";
using (System.IO.TextWriter theTextWriter = new System.IO.StreamWriter(theErrorPath, true))
{
DateTime theNow = DateTime.Now;
theTextWriter.WriteLine("The error time: " + theNow.ToShortDateString() + " " +
theNow.ToShortTimeString());
while (theException != null)
{
theTextWriter.WriteLine("Exception: " + theException.ToString());
theException = theException.InnerException;
}
}
MessageBox.Show("The program crashed. A stack trace can be found at:\n" + theErrorPath);
e.Handled = true;
//Application.Current.Shutdown();
}
MainWindow.xaml.cs:
Public MainWindow()
{
try
{
testForErrors();
}
catch (Exception ex)
{
throw;
}
}
private void testForErrors()
{
var th = new Thread(() =>
{
throw new System.DivideByZeroException();
});
th.SetApartmentState(ApartmentState.STA);
th.IsBackground = true;
th.Start();
}
I've really read all other similar threads on Stackoverflow. Nothing works for me...
I throw an exception of type "Exception" but i can't handle the exception.
I've tried it in the DoWork Progress, in the CompletedEvent (with try/catch, witch e.error....)
void bgGetResponse_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
ConvertByte(myFile);
myFile= null;
}
}
void bgGetResponse_DoWork(object sender, DoWorkEventArgs e)
{
byte[] test= new byte[] { 1, 1, 0, 1, 1};
//Here the error occured (just with throw new Exception("error"))
//The method only throws an exception (for test purposes)
testResponse= _configManager.GetResponse(test, 0);
}
GetResponse(...)
{
throw new Exception("..!");
}
Any ideas?
Thanks for your efforts
I usually just catch it in the work Method and set the result to it.
private void BGW_DoWork(object sender, DoWorkEventArgs e)
{
...
}
catch (Exception ex)
{
e.Result = ex;
}
Then look in the Completed event,
private void BGW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Cursor = Cursors.Default;
try
{
Exception ex = e.Result as Exception;
if (null != ex)
throw ex;
...
If by "can't handle" the exception you mean can't use catch, that's true. You just use the Error property. You could "throw" that in your Completed event handler; but then you stack frame will be different.
e.g.:
try
{
if(e.Error != null) throw(e.Error)
// handle success case
}
catch(MyException exception)
{
// handle specific error.
}
Any unhandled exceptions occuring in the BackgroundWorkers DoWork function will cause the worker to fire RunWorkerCompleted where the event argument will contain the error.