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);
Related
When I run the code it goes to the throw statement on the catch part rather at the place where the user calls it even after re-throwing.If i didn't catch and rethrow it goes into the function.How to prevent getting into the class library code and show the exception at the user level and prevent the user to view the library code.
public void Services(string hostName)
{
try
{
if (hostName!=null)
{
}
else
{
FunctionThatThrowException(hostName);
}
}
catch(Exception e)
{
throw;
}
}
class Program
{
static void Main(string[] args)
{
try
{
using (var ss = new extest()) {
throw new Exception("Exception1");
}
}
catch(Exception ex)
{
System.Console.WriteLine(ex.Message);
}
}
}
class extest : IDisposable
{
public void Dispose()
{
throw new Exception("Exception2");
}
}
Run the codes result is "Exception2",
So I want to know how you can catch two exceptions, or just catch an Exception1.
My project has thousands of such using, which does not add try, but extest's Dispose is only one place, and I hope to know what exception has thrown before the Dispose.
Thanks
The problem in your example is that the second exception is thrown while the first exception is being handled. I.e. the using statement is effectively a try/finally pair, with the call to Dispose() in the finally block. So, the second exception supersedes the first one.
Having a Dispose() method that throws an exception is a very bad idea. So, the best solution here is to fix that. Don't throw an exception from a Dispose() method. But if you can't fix that for some reason and you want to see both, you need to make sure you're in a position to catch both. You can do this by adding another try/catch inside the using:
try
{
using (var ss = new extest()) {
try
{
throw new Exception("Exception1");
}
catch (Exception exInner)
{
System.Console.WriteLine(ex.Message);
throw;
}
}
}
catch(Exception ex)
{
System.Console.WriteLine(ex.Message);
}
The easiest way to handle this would be to rearrange your code:
static void Main(string[] args)
{
try
{
using (var ss = new extest())
{
try
{
CodeThatMightThrowAnException();
}
catch (Exception e)
{
// Process Exception here
}
}
}
catch(Exception ex)
{
System.Console.WriteLine(ex.Message);
}
}
Edit:
If the handling of the exceptions inside the using is always going to be the same, you could build a helper class that could make refactoring easier:
public class TryCatchHelper
{
public Exception Exception { get; private set; } = null;
public void Execute(Action action)
{
try
{
action()
}
catch (Exception e)
{
exception = e;
}
}
}
Then in your method:
static void Main(string[] args)
{
var helper = new TryCatchHelper();
try
{
using (var ss = new extest())
{
helper.Execute(() => {
// Your Code Block Here
});
}
}
catch(Exception ex)
{
// The Dispose threw an exception
}
if (helper.Exception != null)
{
// Handle the exception from the block here.
}
}
it's impossible to catch more than 1 exception.
when you throw Exception2 it should be catched in your catch clause. when you see "Exception2" it is printed by System.Console.WriteLine(ex.Message);. So, you can change the log in catch, or change the throwing exception message in Dispose.
reference added:
class Program
{
static void Main(string[] args)
{
try
{
using (var ss = new extest()) {
...
}
}
catch(Exception ex)
{
System.Console.WriteLine("extest error : " + ex.Message);
}
}
}
class extest : IDisposable
{
public void Dispose()
{
throw new Exception("Dispose failed: reason");
}
}
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.
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.
Let's asume the folowing bit of code, which allows you to call a class in a different AppDomain and handle almost any exception:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace MyAppDomain
{
class Program
{
static void Main(string[] args)
{
AppDomain myDomain = null;
try
{
myDomain = AppDomain.CreateDomain("Remote Domain");
myDomain.UnhandledException += new UnhandledExceptionEventHandler(myDomain_UnhandledException);
Worker remoteWorker = (Worker)myDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Worker).FullName);
remoteWorker.VeryBadMethod();
}
catch(Exception ex)
{
myDomain_UnhandledException(myDomain, new UnhandledExceptionEventArgs(ex, false));
}
finally
{
if (myDomain != null)
AppDomain.Unload(myDomain);
}
Console.ReadLine();
}
static void myDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception ex = e.ExceptionObject as Exception;
if (ex != null)
Console.WriteLine(ex.Message);
else
Console.WriteLine("A unknown exception was thrown");
}
}
public class Worker : MarshalByRefObject
{
public Worker()
{
}
public string DomainName
{
get
{
return AppDomain.CurrentDomain.FriendlyName;
}
}
public void VeryBadMethod()
{
// Autch!
throw new InvalidOperationException();
}
}
}
Now the problem is, allmost any exception can be handled, not every exception. A StackOverflowException for example will still crash the process. Is there a way to detect critical exceptions in different appdomains and handle these by unloading the AppDomain, but still allow other AppDomains to continue?
Unfortunately a StackOverflowException cannot be caught.
See: http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspx
...
Starting with the .NET Framework
version 2.0, a StackOverflowException
object cannot be caught by a try-catch
block and the corresponding process is
terminated by default.
...
Update:
After further investigation in my old issues I found this old thread:
http://www.c-sharpcorner.com/Forums/ShowMessages.aspx?ThreadID=36073
Since .net framework 2.0, a StackOverflowException cannot be catched using a try-catch statement.
http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspx