This question already has answers here:
What happens if a finally block throws an exception?
(11 answers)
Exception thrown in catch and finally. CLR behavior vs. try-catch block [duplicate]
(2 answers)
Closed 3 months ago.
I have a code:
class Program
{
public static void Main()
{
try
{
Execute();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static void Execute()
{
try
{
Step3();
}
catch (Exception ex)
{
Console.WriteLine("catch");
throw new Exception("1");
}
finally
{
Console.WriteLine("finally");
throw new Exception("2");
}
}
public static void Step3()
{
try
{
Console.WriteLine("Step 3");
throw new Exception("step 3");
}
finally
{
Console.WriteLine("Step 3 finally");
}
}
}
and output:
Step 3
Step 3 finally
catch
finally
2
I do not understand what happened with exception throw new Exception("1");. Did it just disappear? Why?
I have read answer about specification but I'm not sure I understand what happened with throw new Exception("1"); Is it still in memory?
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I am trying to aim for a global try catch exception handler as I have several child class
methods that have try catches inside them. So basically I want the parent class method to catch all those
exceptions and log it.
One of the common ones are SQL exceptions.
What is the best approach here to create a common handler which will catch the errors?
Here is an example of what is going on in my application
public class Parent
{
public void ParentMethod()
{
try
{
var childClass = new Child();
var process = childClass.Process();
if (process)
{
// Do this
}
else
{
// raise new Exception
}
}
catch(Exception ex){
WriteToErrorLogger.Error(ex)
}
}
}
public class Child
{
public bool Process()
{
try{
// Do something and save to Database
}
catch (SqlException sqlEx)
{
// log exception
return false;
}
catch (Exception ex)
{
// log exception
return false;
}
}
}
What do you mean? What would make sense would be to do the exact opposite
public class Parent
{
public void ParentMethod()
{
try
{
var childClass = new Child();
var process = childClass.Process();
if (process)
{
// Do this
}
else
{
// raise new Exception
}
}
catch (SqlException sqlEx)
{
WriteToErrorLogger.Error(ex);
}
catch(Exception ex){
WriteToErrorLogger.Error(ex);
}
}
}
Child
public class Child
{
public bool Process()
{
// Do something and save to Database
}
}
If you want to conditionally do it, you could change the child like this
public class Child
{
public bool Process(bool rethrow = false)
{
try{
// Do something and save to Database
}
catch (SqlException sqlEx)
{
if(rethrow) throw;
// log exception
return false;
}
catch (Exception ex)
{
if(rethrow) throw
// log exception
return false;
}
}
}
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");
}
}
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I have 3 Methods, I am try catch for every method. If an error occur in Third method it goes to exception.
private void M1()
{
try
{
//some code
//calling M2()
//some code
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void M2()
{
try
{
//some code
//calling M3()
//some code
}
catch(Exception ex)
{
throw ex;
}
}
private void M3()
{
try
{
//some code
//Error Occur
//some code
}
catch(Exception ex)
{
throw ex;
}
}
Now it goes directly to M1() method and shows Exception. And the another method is
private void M1()
{
try
{
//some code
//calling M2()
//some code
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void M2()
{
try
{
//some code
//calling M3()
//some code
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
}
private void M3()
{
try
{
//some code
//Error Occur
//some code
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
}
After exception also it execute the code in M2() and in M1().
Which Program is best...,
There is nothing good or bad design, only your scenario decided the best approach.
If you want to catch the error on M1 then don't write Try .. catch in M2 and M3.
If you want to handle the error in the function where error was raised then put the Try .. catch in same function.
Consider the following code:
class Foo {
// boring parts omitted
private TcpClient socket;
public void Connect(){
socket.BeginConnect(Host, Port, new AsyncCallback(cbConnect), quux);
}
private void cbConnect(IAsyncResult result){
// blah
}
}
If socket throws an exception after BeginConnect returns and before cbConnect gets called, where does it pop up? Is it even allowed to throw in the background?
Code sample of exception handling for asynch delegate from msdn forum. I beleive that for TcpClient pattern will be the same.
using System;
using System.Runtime.Remoting.Messaging;
class Program {
static void Main(string[] args) {
new Program().Run();
Console.ReadLine();
}
void Run() {
Action example = new Action(threaded);
IAsyncResult ia = example.BeginInvoke(new AsyncCallback(completed), null);
// Option #1:
/*
ia.AsyncWaitHandle.WaitOne();
try {
example.EndInvoke(ia);
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
*/
}
void threaded() {
throw new ApplicationException("Kaboom");
}
void completed(IAsyncResult ar) {
// Option #2:
Action example = (ar as AsyncResult).AsyncDelegate as Action;
try {
example.EndInvoke(ar);
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
}
}
If the process of accepting a connection results in an error your cbConnect method will be called. To complete the connection though you'll need to make the following call
socket.EndConnection(result);
At that point the error in the BeginConnect process will be manifested in a thrown exception.
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);