I have a class which contains several methods.
One of the methods runs in a while loop (MainMethod).
I call out to helper methods in the same class from MainMethod.
The Try Catch is contained within MainMethod where most of the execution occurs.
If an exception occurs in a helper method which doesn't contain a Try Catch, will it be caught further up? i.e. inside MainMethod which called the helper method.
class Class1
{
public MainMethod()
{
while (true)
{
try
{
// ...
// ...
// ...
HelperMethod();
// ...
// ...
}
catch (Exception e)
{
// Console.WriteLine(e.ToString());
// logger.log(e.ToString();
// throw e;
// ...
}
}
}
public HelperMethod()
{
// No Try Catch
// if (today == "tuesday") program explodes.
}
}
Thanks.
Yes. If a method has no try/catch block it will "bubble up" the stack and be caught by the next handler up the chain. If there is no handler, that's when your program terminates because an exception was "unhandled".
Yes it will. Something like this:
public class Helper
{
public void SomeMethod()
{
throw new InvalidCastException("I don't like this cast.");
}
public void SomeOtherMethod()
{
throw new ArgumentException("Your argument is invalid.");
}
}
public class Caller
{
public void CallHelper()
{
try
{
new Helper().SomeMethod();
}
catch (ArgumentException exception)
{
// Do something there
}
catch (Exception exception)
{
// Do something here
}
try
{
new Helper().SomeOtherMethod();
}
catch (ArgumentException exception)
{
// Do something there
}
catch (Exception exception)
{
// Do something here
}
}
}
Note that if caller application handles that specific type of exception, specific catch block will be called.
IMHO, it is good to handle specific exceptions that may be thrown by methods you call from your code. However, that also means that author of method you are calling created a decent document sharing exceptions that we need to expect from his code.
Related
I have the following methods in c#:
void Method1()
{
try
{
Method2();
}
catch(Method2Exception ex)
{
//Log error
}
}
void Method2()
{
if(error)
{
throw(new Method2Exception("error"));
}
//Do something and call method3
try
{
Method3();
}
catch(Method3Exception)
{
//??
}
}
void Method3()
{
//Do something
if(error)
{
throw(new Method3Exception("error"));
}
}
Method3 its gonna be call by different methods and it returns Method3Exception and I need rethrow the exception from Method2 to Method1 but I don't want catch Method3Exception on Method1. what's the best way to do that?
Any suggestions
The term (re)throw usally refer to throwing the exception back to the caller preserving the stack trace (which contains where the exception exactly occurred). This can be done using throw; without specifying the exception operand contrary to throw ex:
try
{
Method3();
}
catch(Method3Exception)
{
throw;
}
However, if you're just going to add a throw with nothing before it in that method. It is useless, just remove the try..catch and the exception is going to propagate to the caller which is the default behavior.
Docs:
A throw statement can be used in a catch block to re-throw the
exception that the catch block caught. In this case, the throw
statement does not take an exception operand.
Alternative way to re-throwing the exception (using throw; as described in other answers) is to wrap the exception in inner exception. As described in MSDN, all custom exceptions should have at least four constructors, and one of them is
public InvalidDepartmentException(string message, System.Exception inner) : base(message, inner) { }
So if all your custom exceptions are like this, you could wrap the exception from Method3 as inner exception:
void Method2()
{
if(error)
{
throw(new Method2Exception("error"));
}
//Do something and call method3
try
{
Method3();
}
catch(Method3Exception exc)
{
throw new Method2Exception("error", exc); // exc is passed as inner exception
}
}
Then if you want to inspect the inner exception in Method1, you can use property InnerException:
void Method1()
{
try
{
Method2();
}
catch(Method2Exception ex)
{
if(ex.InnerException != null)
{
var message = ex.InnerException.Message;
// Do what you need with the message
}
}
}
In Method2, you can throw a new Method2Exception with the existing Method3Exception as its InnerException:
try
{
Method3();
}
catch(Method3Exception method3Exception)
{
throw new Method2Exception("Message", method3Exception);
}
Then you can catch the Method2Exception above:
try
{
Method2();
}
catch(Method2Exception ex)
{
//Log error
}
Exceptions are bubbles up by default. For example,
void FirstMethod()
{
int a = 0;
int b = 10;
int c = b / a;
}
void SecondMethod()
{
FirstMethod();
}
void ThirdMethod()
{
SecondMethod();
}
void FourthMethod()
{
try
{
ThirdMethod();
}
catch (DivideByZeroException ex)
{
// Handle error
}
}
The exception will occur in FirstMethod and it will go upwards and will be cought at ForurthMethod. If you want to log the exception at ThirdMethod for example, but still want your exception to be handled at FourthMethod then you have to options:
First option:
void ThirdMethod()
{
try
{
SecondMethod();
}
catch (Exception ex)
{
// Log the error
throw; // Throw exception without affecting StackTrace
}
}
Second option:
After C# 6.0 you can do this with ease by using exception filters. Create a logger method which returns false.
bool Log(Exception ex)
{
// Log the error
return false;
}
Add exception filter in third method:
void ThirdMethod()
{
try
{
SecondMethod();
}
catch (Exception ex) when(Log(ex))
{
// Debugger won't reach here
}
}
Why base class's try-catch doesn't catches exception thrown in derived class?
Did I missed something?
Base class:
public class UmBase
{
protected Thread ThisThread;
protected UmBase(int cycleMs, UpdateManager updateManager,
string loggerFilename, string loggerFolder = "UpdateManager")
{
}
public void Start()
{
ThisThread = new Thread(Work);
ThisThread.Start();
}
public virtual void Iteration()
{
throw new Exception("Iteration Method should be overidden!");
}
public void Work()
{
while (IsProcessing)
{
try
{
Iteration();
}
catch (Exception exception)
{
Log.Error(exception.Message); //WANT TO HANDLE IT HERE
}
finally
{
Sleep(100);
}
};
}
}
Derived class:
public class ReadParams : UmBase
{
public ReadParams(UpdateManager updateManager, int cycleMs = 60000)
: base(cycleMs, updateManager, "sss")
{
Iteration();
}
public override void Iteration()
{
try
{
DbParams.Set(); //EXCEPTION IS THROWN INSIDE
}
catch (Exception exception)
{
throw new Exception("Oops!", exception);
}
}
}
I've read here Can we catch exception from child class method in base class in C#? and can't find my mistake.
Try/Catch will only catch exceptions thrown in the try block. That includes any exceptions thrown by other methods called within the try block. Have you got exceptions configured to break on just unhandled or also on thrown? See here for how to configure exception breaks
The other possibility is that your exception is being thrown at time of object construction, because your ReadParams constructor calls Iteration() without a try/catch.
i.e.
public class ReadParams : UmBase
{
public ReadParams(UpdateManager updateManager, int cycleMs = 60000)
: base(cycleMs, updateManager, "sss")
{
Iteration();
}
public override void Iteration()
{
try
{
// If throw here (A)
DbParams.Set(); //EXCEPTION IS THROWN INSIDE
}
catch (Exception exception)
{
// I'll catch here (A) and then throw a new exception
throw new Exception("Oops!", exception);
}
}
}
public void Work()
{
while (IsProcessing)
{
try
{
// Exceptions thrown here including the one you
// threw in the method Iteration (B)
Iteration();
}
catch (Exception exception)
{
// Will be caught here (B)
Log.Error(exception.Message); //WANT TO HANDLE IT HERE
}
finally
{
Sleep(100);
}
};
}
If I read it right, the sequence is:
ReadParams ctor
UmBase ctor
ReadParams Iteration
ReadParams Iteration throw new Exception("Oops!", exception);
Crash... because there is no try-catch in ReadParams ctor
When you override a method you actually replace the entire method wholesale as far as instances of the derived class is concerned.
Unless you call the inherited method explicitly from the overridden one, it is not part of your derived class's logic.
I faced same problem .I noticed one thing but not sure of the reason.
When u inherit a base class privately its catch block does not catch the exception of the derived class.
inherit the base class publicly and give it a try.
Is it possible to pass parameters to a catch block?
Here is some example code:
try
{
myTextBox.Text = "Imagine, that could fail";
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
Can I pass the Textbox (myTextBox) now to my catch block if it would fail? smth. like that:
try
{
myTextBox.Text = "Imagine, that could fail";
}
catch (Exception e, TextBox textBox)
{
textBox.BorderBrush = Colors.Red;
MessageBox.Show(e.Message);
}
How I would do that?
No it's not possible by standart.
What you can do, is to define your custom exception and assign parameters there, for example:
public class MyCustomException : Exception
{
public string SomeAdditionalText {get;set;}
....
//any other properties
...
}
and inside the method which raises an exception raise your own MyCustomException
You only catch a single thing, which in C# must be an Exception. So not directly. However! If the Exception were, say, a custom SomethingSpecificException, then you could make that information available on e.SomeProperty.
public class SomethingSpecificException : Exception {
public Control SomeProperty {get;private set;}
public SomethingSpecificException(string message, Control control)
: base(message)
{
SomeProperty = control;
}
...
}
Then at some point you could:
throw new SomethingSpecificException("things went ill", ctrl);
and
catch(SomethingSpecificException ex) {
var ctrl = ex.SomeProperty;
....
}
don't know what you want to achieve, but in the catch block you can access any UI element, as you do in the try block. So for me there is no point of defining an additional parameter in the catch block.
Next to the possibility to use custom exception to distinguish what's going on:
try
{
myClass.DoSomethingThatCouldThrow();
myClass.DoSomethingThatThrowsSomethingElse();
myClass.DoAnotherThingWithAThirdExceptionType();
}
catch(FirstSpecialException ex)
{
// Do something if first fails...
}
catch(SecondSpecialException ex)
{
// Do something if second fails...
}
You could also put every statement into its own exception block. This would make your code quite lengthly, but is maybe the only possibility if you can't change the class to throw any special exception.
try
{
myClass.DoSomethingThatCouldThrow();
}
catch(InvalidOperationException ex)
{
// Do something if it fails...
}
try
{
myClass.DoSomethingThatCouldThrow();
}
catch(InvalidOperationException ex)
{
// Do something if it fails...
}
try
{
myClass.DoAnotherThingWithAThirdExceptionType();
}
catch(InvalidOperationException ex)
{
// Do something if it fails...
}
Due to the fact, that this last, looks a little bit like repetitive code, we could maybe put it into some method with the following body:
public void TryCatch<ExceptionT>(Action tryMethod, Action<ExceptionT> catchMethod)
where ExceptionT : Exception
{
// ToDo: ArgumentChecking!
try
{
tryMethod();
}
catch(ExceptionT ex)
{
catchMethod(ex);
}
}
Which could you then call with:
TryCatch<InvalidOperationException>(
() => myClass.DoSomething(),
(ex) => Console.WriteLine(ex.Message));
I've written a custom exception AbortTestException, which is pretty simple:
class AbortTestException : Exception
{
public AbortTestException(string message)
: base(message) { }
}
Then I have a function that will throw it:
class Foo
{
public void Throws()
{
throw new AbortTestException("hi");
}
}
And Throws() gets called via method reference:
class Program
{
static void Main(string[] args)
{
Type myType = (typeof(Foo));
var method = myType.GetMethod("Throws");
try
{
method.Invoke(new Foo(), null);
}
catch (AbortTestException ex)
{
Console.WriteLine("AbortTestException");
}
catch (Exception ex)
{
Console.WriteLine("Exception");
}
}
}
However, something weird happens. Even though Throws rises an AbortTestException, the catch(Exception) block gets used (instead of the catch(AbortTestException) block). I tried putting the "throw new AbortTestException("hi")" portion in the try block itself, and verified that the correct catch block is used.
Is there some reason an exception would be re-cast when emitted via MethodInfo.invoke()?
http://msdn.microsoft.com/en-us/library/4k9x6bc0.aspx
Per the MSDN a TargetInvocationException is thrown if the invoked method or constructor throws an exception.
Did you check the nested Exception? My guess the original exception (AbortTest...) is wrapped in a nested one. The nested Exception will be in the InnerException property of the one which is caught by your code
Remember that catching Exception will match any exception that isn't caught by a more specific catch block before it:
Type myType = (typeof(Foo));
var method = myType.GetMethod("Throws");
try
{
try
{
method.Invoke(new Foo(), null);
}
catch (AbortTestException ex)
{
Console.WriteLine("AbortTestException");
}
catch(TargetInvocationException tie)
{
throw tie.InnerException;
}
catch (Exception ex)
{
Console.WriteLine("Exception");
}
}
catch(AbortTestException ate)
{
Console.WriteLine("AbortTestException after re-throw from TargetInvocationException");
}
Is there any difference between these tow pieces of code & which approach is better.
try
{
using()
{
//Do stuff
}
}
catch
{
//Handle exception
}
using()
{
try
{
//Do stuff
}
catch
{
//Handle exception
}
}
There are differences, but it namely boils down to the fact that a using block creates it own try and scope blocks.
try
{
using(IDisposable A = GetDisposable())
{
//Do stuff
}
}
catch
{
//Handle exception
// You do NOT have access to A
}
using(IDisposable A = GetDisposable()) //exception here is uncaught
{
try
{
//Do stuff
}
catch
{
//Handle exception
// You DO have access to A
}
}
There's a difference between these blocks. In the second case the exception won't be caught if it is thrown in the using() line (for example instantiating an IDisposable object and the constructor throws an exception). Which one is better will depend on your specific needs.
Yes. In the first, the resource you are "using" will be disposed before the catch block is executed. In the later, it will be disposed afterwards. Moreover, the "foo" statement isn't under the scope of the catch clause. A "using" block is almost syntactic sugar such that
using (foo)
{
}
is
try
{
foo;
}
finally
{
foo.Dispose();
}
Which behaviour is "better" is not obvious without context.
Ultimately, you could combine both methods to overcome both drawbacks:
IFoo f;
try{
f = new Foo();
f.Bar();
catch{
// Do something exceptional with f
} finally{
if(f != null) f.Dispose();
}
As mentioned above, only the first method will catch exceptions in the IDisposable object's initialization, and will have the object in-scope for the catch block.
In addition, the order of operations for the catch and finally blocks will be flipped depending on their nesting. Take the following example:
public class MyDisposable : IDisposable
{
public void Dispose()
{
Console.WriteLine("In Dispose");
}
public static void MethodOne()
{
Console.WriteLine("Method One");
using (MyDisposable disposable = new MyDisposable())
{
try
{
throw new Exception();
}
catch (Exception ex)
{
Console.WriteLine("In catch");
}
}
}
public static void MethodTwo()
{
Console.WriteLine("Method Two");
try
{
using (MyDisposable disposable = new MyDisposable())
{
throw new Exception();
}
}
catch (Exception ex)
{
Console.WriteLine("In catch");
}
}
public static void Main()
{
MethodOne();
MethodTwo();
}
}
This will print:
Method One
In catch
In Dispose
Method Two
In Dispose
In catch
I presume you mean:
using (var x = new Y(params))
{
}
In both cases? Then the obvious difference is the scope of x. In the second case, you could access x in the catch clause. In the first case, you could not.
I'll also take the opportunity to remind you not to "handle" an exception unless you can really do something about it. That includes logging the exception, which would be ok, unless the environment you're operating in does the logging for you (as ASP.NET 2.0 does by default).