C# throw exception to caller - c#

I have a function that needs to throw an exception, but I wanted it to throw that exception to the line where I called that function:
static int retrieveInt()
{
int a = getInt();
if(a == -1)
throw new Exception("Number not found"); //The runtime error is pointing to this line
return a;
}
static void Main(string[] args)
{
int a = retrieveInt(); //The runtime error would be happening here
}

After 2 hours searching I found the answer to my question. To do what I wanted it is needed to user [System.Diagnostics.DebuggerStepThrough] before the function:
[System.Diagnostics.DebuggerStepThrough]
static int retrieveInt()
{
int a = getInt();
if(a == -1)
throw new Exception("Number not found"); //The runtime error will not be here
return a;
}
static void Main(string[] args)
{
int a = retrieveInt(); //The runtime error happens now here
}

The described behaviour is not strictly possible, but working around to the desired effect is.
The issue you're running into is that in Visual Studio, execution pauses and we see exceptions from the most available location with debug info. For framework methods, this means the method call, even though the exception is being thrown a couple of calls deeper. Since the exception is coming from the same project you're debugging, you'll always have debug info for the actual throw line, and thus you'll always reach that line.
The workaround here is to utilize the Call Stack window in VS, which will include a couple lines down the method call which triggered the error, and double-clicking on this will bring you where you want to be, including all local variables at the time of the call. This is analogous to the framework exception behaviour, because if you look at the stack trace, several frames are marked as "external" because they don't have debug info.
EDIT: To add some info about the behaviour of try and catch, catch will respond to any exception not already caught - thus, even if the exception is thrown several calls deeper, if it's not handled by the time the call stack unwinds into your try block, it'll hit the appropriate catch block (if there is one).

How about this ?
public static int NewInt
{
get
{
throw new Exception("Number not found");
}
}
static void Main(string[] args)
{
int a = NewInt;
}

Related

Is there a way to block or assert on accidental recursion in c#

I am working with a large and complex event driven body of code and there are piles of opportunity to accidentally create a recursive condition.
Sometimes the recursive condition is temporary and the application catches up with itself but even that usually creates unnecessary lag. Other times it creates a stackoverflow which is often very difficult to debug when it happens at a client site.
I would like to have a way to either blacklist or whitelist sections of code that are permitted to recurse. If the recursive condition happens during DEV then I want it to assert so that I can correct the code.
What I am considering is having the application examine its own stack to ensure that the method it just entered is not already on the stack.
Any pointers would be appreciated.
Note: This is for a Web Application but I have run into this challenge in multiple environments.
You can inspect stack like this:
[MethodImpl(MethodImplOptions.NoInlining)]
// optionally decorate with Conditional to only be used in Debug configuration
[Conditional("DEBUG")]
public static void FailIfCallerIsRecursive() {
var trace = new StackTrace();
// previous frame is the caller
var caller = trace.GetFrame(1).GetMethod();
// inspect the rest
for (int i = 2; i < trace.FrameCount; i++) {
// if found caller somewhere up the stack - throw
if (trace.GetFrame(i).GetMethod() == caller)
throw new Exception("Recursion detected");
}
}
Then just call it a the beginning:
void MyPotentiallyRecursiveMethod() {
FailIfCallerIsRecursive()
}
But note that it's quite expensive. However since you are going to use that only in dev (debug) configuration - why not. You can also modify it a bit to throw only when certain level of recursion is detected (so caller appears X time up the stack).
You could call the RuntimeHelpers.EnsureSufficientExecutionStack method and then catch the InsufficientExecutionStackException that is thrown if the next method call would cause a (not catchable) StackOverflowException.
You could create an extension method for it:
public static T EnsureSafeRecursiveCall<T>(this Func<T> method)
{
try
{
RuntimeHelpers.EnsureSufficientExecutionStack();
return method();
}
catch (InsufficientExecutionStackException ex)
{
string msg = $"{method.Method.Name} would cause a {nameof(StackOverflowException)} on the next call";
Debug.Fail(msg);
// logging here is essential here because Debug.Fail works only with debug
throw new StackOverflowException(msg, ex); // wrap in new exception to avoid that we get into this catch again and again(note we are in a recursive call)
}
}
Now your original method remains almost unchanged:
public static IEnumerable<T> YourRecursiveMethod<T>(IEnumerable<T> seq)
{
var method = new Func<IEnumerable<T>>(() => YourRecursiveMethod(seq));
return method.EnsureSafeRecursiveCall();
}

How to properly throw an Exception inside yield return method in C#

See edits below for reproducing the behavior that I describe in this problem.
The following program will never end, because the yield return construct in C# calls the GetStrings() method indefinitely when an exception is thrown.
class Program
{
static void Main(string[] args)
{
// I expect the Exception to be thrown here, but it's not
foreach (var str in GetStrings())
{
Console.WriteLine(str);
}
}
private static IEnumerable<string> GetStrings()
{
// REPEATEDLY throws this exception
throw new Exception();
yield break;
}
}
For this trivial example, I could obviously use return Enumerable.Empty<string>(); instead, and the problem goes away. However in a more interesting example, I'd expect the exception to be thrown once, then have the method stop being called and throw the exception in the method that's "consuming" the IEnumerable.
Is there a way to produce this behavior?
EDIT: ok, the problem is different than I first thought. The program above does NOT end, and the foreach loop behaves like an infinite loop. The program below DOES end, and the exception is displayed on the console.
class Program
{
static void Main(string[] args)
{
try
{
foreach (var str in GetStrings())
{
Console.WriteLine(str);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
private static IEnumerable<string> GetStrings()
{
throw new Exception();
yield break;
}
}
Why does the try ... catch block make a difference in this case? This seems very strange to me. Thanks to #AndrewKilburn for his answer already for pointing me to this.
EDIT #2:
From a Command Prompt, the program executes the same in both cases. In Visual Studio Enterprise 2015, Update 2, whether I compile in Debug or Release, the behavior above is what I am seeing. With the try ... catch, the program ends with an exception, and without it Visual Studio never closes the program.
EDIT #3: Fixed
For me, the issue was resolved by the answer by #MartinBrown. When I uncheck Visual Studio's option under Debug > Options > Debugging > General > "Unwind the call stack on unhandled exceptions" this problem goes away. When I check the box again, then the problem comes back.
The behaviour being seen here is not a fault in the code; rather it is a side effect of the Visual Studio debugger. This can be resolved by turning off stack unwinding in Visual Studio. Try going into Visual Studio options Debugging/General and unchecking "Unwind the call stack on unhandled exceptions". Then run the code again.
What happens is that when your code hits a completely unhandled exception Visual Studio is unwinding the call stack to just before the line in your code that caused the exception. It does this so that you can edit the code and continue execution with the edited code.
The issue seen here looks like an infinite loop because when you re-start execution in the debugger the next line to run is the one that just caused an exception. Outside the debugger the call stack would be completely unwound on an unhandled exception and thus would not cause the same loop that you get in the debugger.
This stack unwinding feature can be turned off in the settings, it is enabled by default. Turning it off however will stop you being able to edit code and continue without first unwinding the stack yourself. This however is quite easy to do either from the call stack window or by simply selecting 'Enable Editing' from the Exception Assistant.
The following program will never end
That's false. The program is going to end quite quickly.
because the yield return construct in C# calls the GetStrings() method indefinitely when an exception is thrown.
This is false. It doesn't do this at all.
I'd expect the exception to be thrown once, then have the method stop being called and throw the exception in the method that's "consuming" the IEnumerable.
That's exactly what does happen.
Is there a way to produce this behavior?
Use the code you already provided.
class Program {
static void Main(string[] args) {
try {
foreach (var item in GetStrings()) {
Console.WriteLine();
}
}
catch (Exception ex) {
}
}
private static IEnumerable<string> GetStrings() {
// REPEATEDLY throws this exception
throw new Exception();
yield break;
}
}
Putting it in a try catch causes it to break out and do whatever you want
class Program
{
public static int EnumerableCount;
static void Main(string[] args)
{
EnumerableCount = 0;
try
{
foreach (var str in GetStrings())
{
Console.WriteLine(str);
Console.Read();
}
}
catch (Exception e)
{
Console.WriteLine(e);
Console.Read();
}
}
private static IEnumerable<string> GetStrings()
{
EnumerableCount++;
var errorMessage = string.Format("EnumerableCount: {0}", EnumerableCount);
throw new Exception(errorMessage);
yield break;
}
}
has the following output:
System.Exception: EnumerableCount: 1
at {insert stack trace here}
The execution flow goes into the GetStrings() method the for the first iteration, the exception is thrown and caught in the Main() method. After hitting enter, the program exits.
Removing the try catch in the Main() method causes the exception to go unhandled. The output is then:
Unhandled Exception: System.Exception: EnumerableCount: 1
at {insert stack trace here}
and the program crashes.

Get name of last called method

I have the following code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
try
{
this.CheckValue(true); // call method
}
catch(Exception ex)
{
// how to get here name of last called method
}
}
public int CheckValue(bool sender)
{
var qwe = int.Parse("qwe"); // invoke an exception
return 0;
}
}
I need to get in "catch block" name of last called method (in this case "CheckValue"), but it return that called method is "StringToNumber".
I try to get it using StackTrace:
stackTrace.GetFrame(1).GetMethod().Name; -> "Main"
MethodBase.GetCurrentMethod(); -> "Void .ctor()"
ex.TargetSite.Name; -> "StringToNumber"
It's possible to do this?
Short Answer:
Yes, You can!!!
I'd just play around with Extension Methods and the trick here, is to get the last frame of the desired class, otherwise it would get methods of mscorlib assembly. So here it go:
public static string GetLastCalledMethod<T>(this Exception ex)
{
var stackTrace = new System.Diagnostics.StackTrace(ex);
var lastFrame = stackTrace.GetFrames().FirstOrDefault(frame => frame.GetMethod().DeclaringType.FullName == typeof(T).FullName);
string methodName = string.Empty;
if (lastFrame != null)
methodName = lastFrame.GetMethod().Name;
return methodName;
}
Short Answer:
You can't.
Long Answer:
If you really need to do that, you will need to perform logging code in all the methods you want to track.
You can create a global variable (ugh) to store a MethodInfo with the last called method, and inside every method, set it to MethodBase.GetCurrentMethod(). Then whenever you want, you can examine that variable to see which method set it last.
In your case, you probably are trying to determine which method the exception was thrown in. You are looking at TargetSite, which returns the lowest method in the hierarchy, whereas you seem to want the one immediately below the current method. If simply examining Exception.StackTrace doesn't provide enough information, you might be able to parse out information from StackTrace and use reflection to get a MethodInfo. Usually, the StackTrace is good enough.
You may also be able to throw a new exception in the top-level method, so you can get the TargetSite from the new one.
Summary:
If Exception.StackTrace doesn't provide enough information, then you will either have to:
Perform logging code in each method you want to check for.
Parse out what information you can get from the Exception.
Change the exception throwing scheme to throw a new exception with InnerException set to the original exception.
I don't know why you want to do this.. because this is expected behaviour. The site of the exception is what you're being shown.. within the int.Parse() calls.
That being said.. if you really want to do this, you need to wrap a try.. catch in CheckValue, and re-throw the exception from there, but in a way that breaks the call stack.. like so:
public int CheckValue(bool sender) {
try {
var qwe = int.Parse("qwe"); // invoke an exception
return 0;
}
catch (Exception ex) {
throw ex; // this breaks the call stack and re-throws the exception from here..
}
}
Then, ex.TargetSite.Name == "CheckValue". I'm still not sure why you'd want to do this.. as a stack trace will actually show you where it all unwinds from after failure.

if statement for throwing Exception?

Hi I wanted to ask because I'm not sure if is it propriete using of Exception:
public int Method(int a, int b) {
if(a<b) throw new ArgumentException("the first argument cannot be less than the second");
//do stuff...
}
can I throw Exception after if statement? or should I always use try - catch when it goes with the exceptions?
That is perfectly valid. That is exactly what exceptions are used for, to check for "Exceptions" in your logic, things that weren't suppose to be.
The idea behind catching an exception is that when you pass data somewhere and process it, you might not always know if the result will be valid, that is when you want to catch.
Regarding your method, you don't want to catch inside Method but infact when you call it, here's an example:
try
{
var a = 10;
var b = 100;
var result = Method(a, b);
}
catch(ArgumentException ex)
{
// Report this back to the user interface in a nice way
}
In the above case, a is less than b so you can except to get an exception here, and you can handle it accordingly.
In this case, you don't want to catch the exception. You're throwing it to alert the caller that they've made a mistake in the way they called your method. Catching it yourself would prevent that from happening. So yes, your code looks fine.
That's perfectly fine. You're throwing the exception, not catching/handling it, so you wouldn't need a try/catch block for it.
This is perfectly valid, you can use the same construct even with the constructors.
But What you should not do is
public int Method(int a, int b)
{
try
{
if (a < b)
throw new ArgumentException("the first argument cannot be less than the second");
}
catch (Exception)
{
}
return 0;
}
You've got the right idea. You could use your code like this:
void MyMainMethod()
{
// ... oh, let's call my Method with some arguments
// I'm not sure if it'll work, so best to wrap it in a try catch
try
{
Method(-100, 500);
}
catch (ArgumentException ex)
{
Console.WriteLine(ex.Message);
}
}
public int Method(int a, int b)
{
if (a < b) throw new ArgumentException("the first argument cannot be less than the second");
//do stuff ... and return
}
It might help to look through MSDN's Handling and Throwing Exceptions and Best Practices for Handling Exceptions
What you've done here is perfectly Ok.
A common pattern for arg checks is to wrap the check/throw code in a static "Contract" class ensuring you have a consistent approach to exception management when validating input arguments.
Slightly off topic but if using .NET 4.0 you can also look at the new Code Contracts feature for validation of method input and output.
All above answers are correct but I like to mention one additional point here which I did not see mentioned in any of the answers. The reason why you should throw an exception and not return an integer e.g. 0 or -1 for signalling that an error occurred, is that the returned integer can be mistakenly treated/assumed as a valid result of your method. It is an integer anyway, and your method, after performing its internal logic returns an integer. So the caller of this method can mistakenly treat any returned integer as a valid result, which can lead to bugs down the line. In that case, throwing an exception makes perfect sense.

Can't catch exception thrown by Invoke on a compiled expression

In the class:
private Func<T, object> pony;
In my function:
object newValue;
try {
newValue = pony.Invoke(model as T); // This is the line where I get an exception!
} catch (Exception exception) {
// This code is never run, even though I get an exception two lines up!
if(exception is DivideByZeroException) throw new DivideByZeroException("Division by zero when calculating member " + GetMemberName(), exception);
throw;
}
I expect to get exceptions when I throw them, but I get a DivideByZeroException on the line newValue = pony.Invoke(model as T);. Why is this? Can I do something about it?
This is in a asp.net mvc2-application running in Cassini at the moment.
If I select Start debugging in Visual Studio 2008, the error gets caught and rethrown with the extra information!
The problem was that I obviously haven't understood how inner exceptions work. The exception gets caught but then only the inner exception is shown, and that's a totally other issue.
Exceptions thrown from a compiled expression are handled normally by the try .. catch construct, so I'd expect that there is some other issue in your code. If you try for example the following code, it behaves as expected:
Expression<Func<int, int>> f = x => 10 / x;
Func<int, int> fcompiled = f.Compile();
try {
Console.WriteLine(fcompiled(0));
} catch (DivideByZeroException e) {
Console.WriteLine("Divison by zero");
}
As a side note, you should probably handle DivideByZeroException using a separate catch (as I did in my example). This is a cleaner and recommended way to catch different types of exceptions.
Can you check whether the exception is really unhandled when running the application without debugging (for example by adding some debug print to the catch block)? What exception is printed when you run the application (afterall, your code rethrows some exception in any case, so the output may not be clear).
The following code worked for me (this is in a C# console app, although I don't know why that would work differently from ASP.NET):
class Program
{
static void Main(string[] args)
{
var foo = new Foo<int>();
try
{
Console.WriteLine("Calling function");
foo.DoStuff(5);
}
catch(Exception ex)
{
Console.WriteLine("Caught exception: " + ex.ToString());
}
finally
{
Console.WriteLine("In finally block");
}
}
}
class Foo<T>
{
private Func<T, object> pony;
public Foo()
{
this.pony = m =>
{
throw new DivideByZeroException("Exception!");
};
}
public object DoStuff(T o)
{
return this.pony.Invoke(o);
}
}
This prints out the contents of the exception to the command line, as expected.
Well, the code executed in the compiled expression obviously generates the DivideByZeroException, right. Something tries to divide by zero in that. So what else would you expect?
Note that the debugger (especially VS) may break on exceptions, so that you should make sure to continue running the application, it should reach your catch block just fine.

Categories