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;
Related
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 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
Suppose I have an exception throw in the message loop:
private void timer1_Tick(object sender, EventArgs e)
{
throw new Exception("yehaaaa!!!!");
}
By default, this throws & displays the generic error dialog to user. (that's what I want)
However if I add the following subscription to Application.ThreadException:
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
//_raygunClient.Send(e.Exception);
}
Then the exception is swallowed.
Why?
& how can I have it throw to the user normally?
It's all right there in the reference source:
internal void OnThreadException(Exception t) {
if (GetState(STATE_INTHREADEXCEPTION)) return;
SetState(STATE_INTHREADEXCEPTION, true);
try {
if (threadExceptionHandler != null) {
threadExceptionHandler(Thread.CurrentThread, new ThreadExceptionEventArgs(t));
}
else {
if (SystemInformation.UserInteractive) {
ThreadExceptionDialog td = new ThreadExceptionDialog(t);
If there is a handler it is invoked otherwise some standard code is run. If you want to show the standard dialog, use ThreadExceptionDialog and handle the DialogResult the same way. In my own code there is something to this effect, which seems to work:
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
Exception exception = e.Exception;
_Logger.Error(e.Exception, "An unhandled forms application exception occurred");
// Show the same default dialog
if (SystemInformation.UserInteractive)
{
using (ThreadExceptionDialog dialog = new ThreadExceptionDialog(exception))
{
if (dialog.ShowDialog() == DialogResult.Cancel)
return;
}
Application.Exit();
Environment.Exit(0);
}
}
I have a code like this,
using (SPSite site = new SPSite("http://site/"))
{
using (SPWeb web = site.OpenWeb())
{
try
{
SPList list = web.Lists["ListName"]; // 2
SPListItem item = list.Items.Add();
Guid itemId = item.UniqueId;
SPListItem itemUpdate = web.Lists["ListName"].Items[itemId];
itemUpdate["PercentComplete"] = .45; // 45% HERE IS EXCEPTION
itemUpdate.Update();
}
catch (Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
}
}
}
I am getting this exception on line itemUpdate["PercentComplete"]
Value does not fall within the expected range.
What I want is
I want this exception to be ignored as if it returns null then keep it null instead of throwing exception,
I already tried this,
Object letSay = itemUpdate["PercentComplete"];
// thought object can be null but same exception
I don't want to try
try {} and Catch {} either.
You just need to check this field existance:
SPListItem item = list.Items.Add();
if (item.Fields.ContainsField("PercentComplete"))
{
item["PercentComplete"] = .45;
}
item.Update();
Not sure because I don't use Sharepoint,but looking at the docs you need to create the field "PercentComplete" before trying to set a value in it.
SPListItem itemUpdate = web.Lists["ListName"].Items[itemId];
itemUpdate.Fields.CreateNewField("PercentComplete", "PercentComplete");
itemUpdate["PercentComplete"] = .45;
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splistitem.fields.aspx
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfieldcollection_methods.aspx
Let's hope an expert on SharePoint could give you a better answer.....
As a side note: There is no way to ignore an exception. Exceptions are an 'exceptional' event. Something that you cannot expect, not something that you could prevent to happen with proper coding. Accessing an item that doesn't exist is a bad practice and you could easily avoid it.
If you wish you could setup a global exception handler that handles all the uncaught exception adding code like this to your main method
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
And then prepare the following methods
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
string msg = "Not recognized error:" + e.Exception.Message;
if (e.Exception.InnerException != null)
{
msg = msg + "\r\nPrevious error:" + e.Exception.InnerException.Message;
}
msg = msg + "\r\nStackTrace:" + e.Exception.StackTrace;
msg = msg + "\r\nDo you wish to continue with the application?";
DialogResult dr = AskAQuestion(msg);
.. add logging here ...
if (dr == DialogResult.No) Application.Exit();
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception ex = e.ExceptionObject as Exception;
if (ex != null)
{
string msg = "Not recognized error:" + e.Exception.Message;
if (e.Exception.InnerException != null)
{
msg = msg + "\r\nPrevious error:" + e.Exception.InnerException.Message;
}
msg = msg + "\r\nStackTrace:" + e.Exception.StackTrace;
.. add logging here ...
}
}
According to your comment to Steve's answer:
but i wanted to know how can i ignore exception in c#, above code is just an example sir
You cannot ignore an exception in C# without using a try-catch-block. In your case the code should look like this:
try
{
itemUpdate["PercentComplete"] = .45; // 45% HERE IS EXCEPTION
}
catch
{
}
But this code is neither nice, nor should one simply ignore exceptions in first place!
I'm trying to get an unhandled exception handler to work but it doesn't seem to be doing anything. I have to following in the constructor:
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
And this furthur down
static void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.ExceptionObject;
if (log != null)
{
if (args.IsTerminating)
log.LogError(e.Message, e.Source, e.InnerException.Message);
else
log.LogWarning(e.Message, e.Source, e.InnerException.Message);
}
else
{
System.Reflection.Assembly exe = System.Reflection.Assembly.GetEntryAssembly();
string exeDir = System.IO.Path.GetDirectoryName(exe.Location);
File.WriteAllText(DocuPath.Join(exeDir, "Emergency.log"), e.ToString());
}
}
log is a static object which handles logging to a file. Why don't I get a message in either the log file written to by the object or Emergency.log?
If e.InnerException is null you get an exception inside this method.
I don't think it is a good idea to have this problem here.
Try with this.
string innerMessage = e.InnerException != null ? e.InnerException.Message : string.Empty;
if (args.IsTerminating)
log.LogError(e.Message, e.Source, innerMessage);
else
log.LogWarning(e.Message, e.Source, innerMessage);