I would like to catch unhandled exceptions in a windows service application in the class that inherits from ServiceBase class.
I have already tried incorporating the code:
AppDomain.CurrentDomain.UnhandledException += (s, e) =>
{
var exception = (Exception)e.ExceptionObject;
Log.Error("Unhandled exception", exception);
};
But that doesn't work.
Try this:
// Starts the application.
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
public static void Main(string[] args)
{
// Add the event handler for handling non-UI thread exceptions to the event.
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
// Runs the application.
Application.Run(new ErrorHandlerForm());
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
try
{
Exception ex = (Exception)e.ExceptionObject;
string errorMsg = "An application error occurred. Please contact the adminstrator " +
"with the following information:\n\n";
// Since we can't prevent the app from terminating, log this to the event log.
if (!EventLog.SourceExists("ThreadException"))
{
EventLog.CreateEventSource("ThreadException", "Application");
}
// Create an EventLog instance and assign its source.
EventLog myLog = new EventLog();
myLog.Source = "ThreadException";
myLog.WriteEntry(errorMsg + ex.Message + "\n\nStack Trace:\n" + ex.StackTrace);
}
catch (Exception exc)
{
try
{
MessageBox.Show("Fatal Non-UI Error",
"Fatal Non-UI Error. Could not write the error to the event log. Reason: "
+ exc.Message, MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
finally
{
Application.Exit();
}
}
}
You also can take a look at this example: https://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx
Related
I am catching an exception and processing it.
Somewhere up the call tree, I am doing the same.
Once I process my exception at the child level, I want to also go ahead and invoke the exception handler, wherever it is, somewhere up the call tree.
For that, I thought I would do run the throw again.
But instead of breaking somewhere up the call tree, it is breaking in the place where I am doing the throw and crashing, at this line:
throw new Exception("Cannot Write Header Row to Database " + Msg);
code:
public static void NewHeaderRow(string FILE_REV_NUMBER, DateTime FILE_CREATE_DATE, string EDC_DUNS_NUMBER, int RunId)
{
SqlConnection connection = null;
try
{
connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DbConn"].ToString());
connection.Open();
SqlCommand com;
com = new SqlCommand("dbo.INSERT_PPL_HEADER", connection);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.Add(new SqlParameter("#FILE_REV_NUMBER", FILE_REV_NUMBER));
com.Parameters.Add(new SqlParameter("#FILE_CREATE_DATE", FILE_CREATE_DATE));
com.Parameters.Add(new SqlParameter("#EDC_DUNS_NUMBER", EDC_DUNS_NUMBER));
com.Parameters.Add(new SqlParameter("#RunId", RunId));
if (com.Connection.State == ConnectionState.Closed) com.Connection.Open();
com.ExecuteNonQuery();
}
catch (Exception e)
{
string Msg;
Msg = "Encountered unexpected program issue. Please contact your program administator. Error details...";
Msg = Msg + System.Environment.NewLine;
Msg = Msg + System.Environment.NewLine;
Msg = Msg + e.ToString();
Msg = Msg + System.Environment.NewLine;
Msg = Msg + System.Environment.NewLine;
Msg = Msg + e.Message;
throw new Exception("Cannot Write Header Row to Database " + Msg);
}
finally
{
if (connection == null) { } else connection.Close();
}
}
Try just using the throw keyword, instead of building a new exception.
https://stackoverflow.com/a/2999314/5145250
To add additional information to the exception warp it in another exception object and pass the original exception as argument with new message to keep the original stack trace in inner exception.
throw new Exception("Cannot Write Header Row to Database " + Msg, e);
At some top level you should handle global exceptions to avoid crashing.
The way I was finally able to pin point the problem was to extremely simplify my code so as to be able to see the problem clearly. I just copied my solution to a new location, and gutted out all the non-essential stuff -- stuff I knew was not going to be important for the purposes of troubleshooting.... Very effective way of troubleshooting difficult problems that are hard to trace.... Here is what I ended up with (the simple code).
I was not catching general exception in the code that calls NewHeaderRow.
I was catching System.IO exception.
So, because code had nowhere to go, it crashed....
It is very hard for the eyes to catch this error and also difficult to trace.
private void button1_Click(object sender, EventArgs e)
{
LoadFile();
}
private static int ProcessHeaderRow(string line)
{
int LoadRunNumber = 0;
try
{
//some complex logic was here; error occurs here, so I throw an exception....
throw new Exception("An Error Occurs -- Process Header Row Try block");
}
catch (CustomExceptionNoMessage e)
{
throw new CustomExceptionNoMessage(e.Message);
}
catch (Exception e)
{
//Process the exception, then rethrow, for calling code to also process the exception....
//problem is here...XXXXXXXXXXXXXXXXXX
throw new Exception(e.Message); //crashes
}
return LoadRunNumber;
}
public static bool LoadFile()
{
int RunId = 0;
try
{
RunId = ProcessHeaderRow("10~~happy~007909427AC");
MessageBox.Show("Completed Upload to Cloud...");
}
catch (CustomExceptionNoMessage ce)
{
MessageBox.Show(ce.Message);
}
catch (System.IO.IOException e) //CHANGED THIS LINE, AND I AM UP AND RUNNING (Changed to Exception e)
{
MessageBox.Show(e.Message);
}
return true;
}
public class CustomExceptionNoMessage : Exception
{
public CustomExceptionNoMessage()
{
}
public CustomExceptionNoMessage(string message)
: base(message)
{
}
public CustomExceptionNoMessage(string message, Exception inner)
: base(message, inner)
{
}
}
private void button1_Click(object sender, EventArgs e)
{
LoadFile();
}
How to catch all exceptions in try catch block in Xamarin.Android
I am very frustrated on how Xamarin.Android handles unhandled exception which is very weird, I added three exceptions for all api queries respectively:
try
{
// api query using `refit`
// json parsing using `newtonsoft`
}
catch(System.OperationCanceledException e)
{
// user cancelled the query, show option to retry
}
catch(ApiException apiException)
{
// theres an api exception , show error message to users , show option to retry
}
catch(Exception e)
{
// unknown exception ignore , show error message to users , show option to retry
}
This try catch blocks works most of the time, but there is one certain scenario when our server is down, and it just throws exception and crashes the app over and over again until the server is back up.
This is the exception that keeps on bugging us :
Xamarin caused by: android.runtime.JavaProxyThrowable: Newtonsoft.Json.JsonReaderException
As you can see in JsonReaderException hierarchy, it inherited System.Exception which is the last catch block i used.
and I checked this JsonReaderException it extends from Exception , In which our try catch block should handle it.
Now im wondering is there any way that we can catch all those pesky unhandled exceptions?
I'm getting unhandled exceptions in this way
public void Init()
{
AndroidEnvironment.UnhandledExceptionRaiser += OnAndroidEnvironmentUnhandledExceptionRaiser;
AppDomain.CurrentDomain.UnhandledException += OnCurrentDomainUnhandledException;
TaskScheduler.UnobservedTaskException += OnTaskSchedulerUnobservedTaskException;
var currentHandler = Java.Lang.Thread.DefaultUncaughtExceptionHandler;
var exceptionHandler = currentHandler as UncaughtExceptionHandler;
if (exceptionHandler != null)
{
exceptionHandler.SetHandler(HandleUncaughtException);
}
else
{
Java.Lang.Thread.DefaultUncaughtExceptionHandler = new UncaughtExceptionHandler(currentHandler, HandleUncaughtException);
}
}
private void OnAndroidEnvironmentUnhandledExceptionRaiser(object sender, RaiseThrowableEventArgs e)
{
AndroidEnvironment.UnhandledExceptionRaiser -= OnAndroidEnvironmentUnhandledExceptionRaiser;
_logger.LogFatal($"AndroidEnvironment.UnhandledExceptionRaiser.", e.Exception);
e.Handled = true;
}
private void OnCurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
AppDomain.CurrentDomain.UnhandledException -= OnCurrentDomainUnhandledException;
var ex = e.ExceptionObject as Exception;
if (ex != null)
{
_logger.LogFatal("AppDomain.CurrentDomain.UnhandledException.", ex);
}
else
{
_logger.LogFatal($"AppDomain.CurrentDomain.UnhandledException. ---> {e.ExceptionObject}");
}
}
private void OnTaskSchedulerUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
_logger.LogFatal("TaskScheduler.UnobservedTaskException.", e.Exception);
}
private bool HandleUncaughtException(Java.Lang.Throwable ex)
{
_logger.LogFatal("Thread.DefaultUncaughtExceptionHandler.", ex);
return true;
}
I am unable to get the reason for this Exception:
private void bwWorker_DoWork(object sender, DoWorkEventArgs e)
{
if (Main.bolDebugMode)
MessageBox.Show("Function DoWork is called");
if (Main.ftpsync(Main.strUsername407, Main.strPassword407, sender as BackgroundWorker) == 0)
e.Result = e.Result + "No error in " + Main.strUsername407;
else
{
if (Main.bolDebugMode)
MessageBox.Show("Errors in " + Main.strUsername407);
e.Cancel = true;
e.Result = e.Result + "Errors in " + Main.strUsername407;
if (Main.bolDebugMode)
MessageBox.Show("Errors marked");
try
{
MessageBox.Show("Next step throws exception");
return;
}
catch (Exception error)
{
if (error.ToString() != null)
MessageBox.Show(error.InnerException.Message);
}
}
}
It throws this exception:An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
Additional information: Exception has been thrown by the target of an invocation.
The target (to my limited understanding) is the backgroundworker's RunWorkerCompleted function:
private void bwWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (Main.bolDebugMode)
MessageBox.Show("DoWork Completed. Break: " + e.Cancelled + " Error: " + e.Error + " Result: " + e.Result);
// First, handle the case where an exception was thrown.
if (e.Error != null)
{
lStatus.Text = e.Error.Message;
}
else if (e.Cancelled)
lStatus.Text = "Cancelled: " + e.Result.ToString();
}
else
{
lStatus.Text = "Done! " + e.Result;
Thread.Sleep(Convert.ToInt16(Main.strGlobalWaitTime));
pbProgress.Value = 0;
lStatus.Text = "";
}
if (Main.bolDebugMode)
MessageBox.Show("Analysis completed");
// Enable the Start button.
btnStart.Enabled = true;
// Disable the Cancel button.
btnCancel.Enabled = false;
}
public class Main
{
#region Variables
// Variables - FTP Settings
// Reading tons of variables from a appconfig file like so:
private static string StrGlobalWaitTime = ConfigurationManager.AppSettings["program_globalWaitTime"];
private static bool BolDeleteRemoteFiles = Convert.ToBoolean(ConfigurationManager.AppSettings["program_deleteremotefiles"]);
// Configuring the variables to receive and write
public static string strGlobalWaitTime
{
get { return StrGlobalWaitTime; }
set { StrGlobalWaitTime = value; }
}
#endregion
#region Main function
public static int ftpsync(string strUsername, string strPassword, BackgroundWorker bwWorker)
{
if (Directory.EnumerateFiles(strWorkDirectory, "*.pdf").Any())
{
bwWorker.ReportProgress(0, "Files left! Upload not complete");
Thread.Sleep(Convert.ToInt16(Main.strGlobalWaitTime));
return 1;
}
However, it doesn't even reach the first debugging message box. Thus it must be happening between the return and the beginning of the function. Is he background worker not handing over directly to the RunWorkerCompleted function? Can anyone tell me what I am missing or doing wrong?
This is my first question. I will try to provide as much information as possible. Google searches for the most obvious queries have been done.
The thing to look for whenever you encounter a TargetInvocationException is the InnerException property, which will have the "real" exception.
From the look of it, it will most likely have something to do with trying to access the GUI from inside the worker's thread. Remember that when using the DoWork handler, the code executes in a different thread from the main UI's. Therefore, calls to GUI components must be either done via Invoke calls or avoided all together.
I'm using the UndhandledException provided by the AppDomain, what I did is essentially this:
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionTrapper;
}
static void UnhandledExceptionTrapper(object sender, UnhandledExceptionEventArgs e)
{
e.ExceptionObject.Message? <- there is no message
Console.WriteLine(e.ExceptionObject.ToString());
Console.WriteLine("Press a key for exit.");
Console.ReadLine();
Environment.Exit(1);
}
how you can see I can't access to the message property, but if I set a break point I can see on the e variable the Message property, why I can't use this?
The problem is that ExceptionObject is an object. You can cast it to Exception in order to get the Message
var exception = (e.ExceptionObject as Exception);
if (exception != null)
{
message = exception.Message;
}
or MSDN suggests to cast it this way
Exception exception = (Exception) e.ExceptionObject;
var message = exception.Message;
I am using GCMlibrary in C#. I have implemented different handlers that check whether message is sent or not. How can I check handler that is for
ChannelException
ChannelDestroyed
ServiceException
How can I check when exception come in these events.
I have declared handler like this
static void ChannelException(object sender, IPushChannel channel, Exception exception)
{
CLogger.WriteLog(ELogLevel.INFO, "Channel Exception: " + sender + " -> " + exception);
// Console.WriteLine("Channel Exception: " + sender + " -> " + exception);
}
static void ServiceException(object sender, Exception exception)
{
CLogger.WriteLog(ELogLevel.INFO, "Service Exception: " + sender + " -> " + exception);
string test= exception.Message;
// Console.WriteLine("Channel Exception: " + sender + " -> " + exception);
}
static void ChannelDestroyed(object sender)
{
CLogger.WriteLog(ELogLevel.INFO, "Channel Destroyed for: " + sender);
// Console.WriteLine("Channel Destroyed for: " + sender);
}
To handle exceptions in events in C# use the sample from MSDN. Use the following events raise approach:
public class Pub
{
public event EventHandler OnChange = delegate { };
public void Raise()
{
var exceptions = new List<Exception>();
foreach (Delegate handler in OnChange.GetInvocationList())
{
try
{
handler.DynamicInvoke(this, EventArgs.Empty);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
}
if (exceptions.Any())
{
throw new AggregateException(exceptions);
}
}
}
Catch exceptions as mentioned:
public void CreateAndRaise()
{
Pub p = new Pub();
p.OnChange += (sender, e)
=> Console.WriteLine(“Subscriber 1 called”);
p.OnChange += (sender, e)
=> { throw new Exception(); };
p.OnChange += (sender, e)
=> Console.WriteLine(“Subscriber 3 called”);
try
{
p.Raise();
}
catch (AggregateException ex)
{
Console.WriteLine(ex.InnerExceptions.Count);
}
// Displays
// Subscriber 1 called
// Subscriber 3 called
// 1
}
If you are unable to change existing event handlers, then:
Write your own event handler, which wraps existing, for example ChannelEventCustom.
In its raise method, wrap existing event execution (for example ChannelEvent) in try-catch block
That's all. Here is short guide how to create your own events