Java.Lang.Thread.DefaultUncaughtExceptionHandler catches only exceptions by the Android runtime. I tried to throw a native exception with
Java.Lang.Integer.ParseInt("xxx");
but the exception is not catched by the DefaultUncaughtExceptionHandler. This is my implementation:
Application subclass:
// OnCreate
UncaughtExceptionHandler uncaughtHandler = new UncaughtExceptionHandler();
uncaughtHandler.UncaughtExceptionHandled += OnUncaughtExceptionHandled;
Java.Lang.Thread.DefaultUncaughtExceptionHandler = uncaughtHandler;
private void OnUncaughtExceptionHandled(object sender, Throwable ex)
{
Console.WriteLine("DefaultUncaughtExceptionHandler");
}
Additional class:
private class UncaughtExceptionHandler : Java.Lang.Object, Java.Lang.Thread.IUncaughtExceptionHandler
{
public event EventHandler<Throwable> UncaughtExceptionHandled;
public void UncaughtException(Java.Lang.Thread thread, Throwable ex)
{
if (UncaughtExceptionHandled != null)
{
UncaughtExceptionHandled(null, ex);
}
}
}
How can I throw an exception that is catched by the DefaultUncaughtExceptionHandler? Is it a good idea to catch unmanaged exceptions in managed code?
You need just a throw new Exception after UncaughtExceptionHandler was initialized
throw new DivideByZeroException();
Is it a good idea to catch unmanaged exceptions in managed code?
Yeap. Crashlytics(Crash Report Library) - works in the same way.
Related
I am working with a few methods that are called from within other methods, but need to stop processing both methods if an event occurs in the one called from the parent. An example of what I am doing in code would be this:
private void parentMethod()
{
//Do work here
childMethod();
//Do more work here
}
private void childMethod()
{
//Do work (not child labor)
using (var form = new choice(myList))
{
var result = form.ShowDialog();
if (result == DialogResult.OK)
{
int val = form.listIndex;//values preserved after close
//Do something here with these values
string server = myList2[val - 1];
MyList.Clear();
MyList.Add(server);
}
else
{
Exception e = new Exception("Dialog force closed.",null);
throw e;
}
}
So as you can see here, I tried creating an exception to throw; however, because there are number of other methods getting called from the parent method which also can throw exceptions, but can allow the rest of the code to execute, and the parent method in this example is being called from another method that needs to be stopped as well, how do you stop the execution of multiple methods from within a child method, other that doing Application.Close()?
You need to be more specific in your exception catching. In general, a bare catch is bad practice anywhere except the very top level, as is catch (Exception e) or similar. You should determine which exceptions a method can throw, and then only catch those. Other exceptions will then be passed back up the call stack.
For instance, if you have a method A() that might throw an InvalidOperationException, B() that might throw an ArgumentOutOfRangeException or ArgumentNullException, and C() that might throw an AccessViolationException, your code should look like
public int Main()
{
try
{
try
{
A()
}
catch(InvalidOperationException e)
{
//handle
}
try
{
B()
}
catch(ArgumentOutOfRangeException e)
{
//handle
}
catch(ArgumentNullException e)
{
//handle
}
try
{
C()
}
catch(AccessViolationException e)
{
//handle
}
}
catch (Exception e)
{
//handle all other exceptions
}
}
Now, if any method out of A,B, and C throws an exception you're not expecting, it will be handled by the final catch block.
If you really must have an exception that can only be handled at the top level, it might be a good idea to create your own Exception class:
class MyApplicationException : Exception { }
Then, as long as you never use catch (Exception) anywhere other than at the top level, you will be fine.
So I have this exception I want to throw if something goes wrong. But it acts strange.
public Calendar LoadCalendar(){
...
if (cal == null)
{
throw new NotImplementedException();
}
_lastPollTime = DateTime.Now;
...
}
I expect this exception to be thrown to wherever LoadCalendar was called. Instead, the program stops at DateTime.Now; because of "NotImplementedException()".
What am I doing wrong? How could I throw it to the end of the method instead?
You need to add a "catch" clause somewhere up the call stack which receives the thrown exception and deals with it somehow.
You could try this in your programs Main function:
static void Main()
{
try
{
// put existing code here
}
catch( Exception e )
{
}
}
Without a catch, the exception has no place to go to and so instead it causes your program to terminate.
These guidlines for working with exceptions might be useful to you: http://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET
Just subscribe DispatcherUnhandledException event in App.xaml.cs Class Constructor and you can handle any application exception in this event.
public partial class App : Application
{
public App()
{
this.DispatcherUnhandledException += App_DispatcherUnhandledException;
}
void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
////Handle your application exception's here by e.Exception.
}
}
Is there a way to catch and handle an exception for all exceptions thrown within any of the methods of a class library?
I can use a try catch construct within each method as in sample code below, but I was looking for a global error handler for a class library. The library could be used by ASP.Net or Winforms apps or another class library.
The benefit would be easier development, and no need to repeatedly do the same thing within each method.
public void RegisterEmployee(int employeeId)
{
try
{
....
}
catch(Exception ex)
{
ABC.Logger.Log(ex);
throw;
}
}
You can subscribe to global event handler like AppDomain.UnhandledException and check the method that throws exception:
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
{
var exceptionObject = unhandledExceptionEventArgs.ExceptionObject as Exception;
if (exceptionObject == null) return;
var assembly = exceptionObject.TargetSite.DeclaringType.Assembly;
if (assembly == //your code)
{
//Do something
}
}
I'm trying to show a custom exception message while preserving the inner exception.
Here is my sample code:
public class Class1
{
public Class1()
{
try
{
throw new WebException("Initial Exception");
}
catch (WebException we)
{
throw new myException("Custom Message", we);
}
}
}
public class myException : WebException
{
public myException(string msg, WebException e) : base(msg, e) { }
}
When I run this code it shows me the custom message in the debugger:
yet still sends the innerexception message to the client:
What am I doing wrong here? How do I preserve the inner exception while showing my own custom message?
The way to customise the message the user sees is to provide a custom error page.
http://support.microsoft.com/kb/306355
I suspect it's because the ApplicationException isn't being effectively handled and the catch block throws an exception which is then being picked up as a base Exception. The debugger is then listing both exceptions.
I think this will give the behaviour you're after (I've written as a console app)
using System;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
myException exception;
try
{
throw new ApplicationException("Initial Exception");
}
catch (ApplicationException e)
{
exception = new myException("Custom Message", e);
}
catch (Exception e)
{
throw e;
}
if (exception != null)
{
throw exception;
}
}
}
}
public class myException : ApplicationException
{
public myException(string msg, ApplicationException e) : base(msg, e) { }
}
If you wrap a call to HttpResponse.End within a try catch block, the ThreadAbortException would automatically be re-raised. I assume this is the case even if you wrap the try catch block in a try catch block.
How can I accomplish the same thing? I do not have a real-world application for this.
namespace Program
{
class ReJoice
{
public void End() //This does not automatically re-raise the exception if caught.
{
throw new Exception();
}
}
class Program
{
static void Main(string[] args)
{
try
{
ReJoice x = new ReJoice();
x.End();
}
catch (Exception e) {}
}
}
}
You can't change ordinary exceptions to have this behaviour. ThreadAbortException has special support for this that you can't implement yourself in C#.
ThreadAbortException is a special exception that can be caught, but it will automatically be raised again at the end of the catch block.
It's as simple as using the plain throw statement.
throw;
in the relevant catch block. Note that this is advantageous over doing throw e; because it preserves the call stack at the point of the exception.
Of course, this isn't automated in perhaps the sense you want, but unfortunately that is not possible. This is pretty much the best solution you'll get, and pretty simple still I think. ThreadAbortException is special in the CLR because it is almost inherent in thread management.
In the case of your program, you'd have something like:
namespace Program
{
class ReJoice
{
public void End()
{
throw new Exception();
}
}
class Program
{
static void Main(string[] args)
{
try
{
ReJoice x = new ReJoice();
x.End();
}
catch (Exception e)
{
throw;
}
}
}
}
You mean like this?
namespace Program
{
class ReJoice
{
public void End() //This does not automatically re-raise the exception if caught.
{
throw new Exception();
}
}
class Program
{
static void Main(string[] args)
{
try
{
ReJoice x = new ReJoice();
x.End();
}
catch (Exception e) {
throw e;
}
}
}
}
Edit: It doesn't re-raise the exception because the meaning of "catch" is to handle the exception. It is up to you as the caller of x.End() what you want to do when an exception occurs. By catching the exception and doing nothing you are saying that you want to ignore the exception. Within the catch block you can display a message box, or log the error, kill the application entirely, or rethrow the error with additional information by wrapping the exception:
throw new Exception("New message", e);