How can I bypass a stackoverflow exception or is there a better way to do this? Any help is greatly appreciated!
public MetricItemDetail GetData(int itemId, int itemTwoId)
{
//some of my code goes here..
try
{
return new Class
{
Value = GetItemDetails(itemId, itemIdTwo)
};
}
catch (Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
return new Class();
}
}
public double GetItemDetails(int itemId, int itemTwoId)
{
var currentValue = GetData(itemId, itemTwoId); // The problem is here..this is where I get the stackoverflow exception
}
GetItemDetails and GetData methods are mutually called, it causes the "infinite" loop with stack allocations for each call, unfortunatelly stack size isn't infinite ;)
See more details here: https://www.dotnetperls.com/stackoverflowexception
StackOverflowException can't be bypased, it can't be catched, it must be avoided. It exists to protect .NET runtime from fatal crash.
Related
How to check if a function throws an exception in c#?
public List<string> GetFileNames()
{
try
{
// do something
// return something
}
catch(Exception ex)
{
// do something
// log something
}
}
then i will call GetFileNames() somewhere in my code, but I want to check if it throws an exception,
like,
var list = GetFileNames(); // can be 0 count
if(GetFileNames() throws an error)
{
DoThisMethod()
}
else
{
DoThisOtherMethod();
}
You have a lot of options here:
This is generally done with a Try... pattern like TryParse.
bool TryGetFileNames(out List<string> fileNames)
You can also return null.
You can"t do this in c#.
The closest thing to what you are describing is the "checked exceptions" which are implemented in java. In such case the function will declare it is throwing some exception like so :
public void foo() throws IOException {
// your code
}
At compile time you will be forsed to take care of this by either enclosing this in TryCatch block or propagate this the same way in your function.
In c# enclose the function in TryCatch block and use different function in case of faliure.
The fundamental problem is that you're attempting to handle an exception when you're not able to do so.
If GetFilenames cannot recover from the exception, it should throw an exception itself. That may be by omitting a try/catch entirely, or by catching it, wrapping and re-throwing.
public List<string> GetFilenames() {
try {
...
} catch (Exception e) {
throw new FileLoadException("Failed to get filenames", e);
// Or if you don't want to create custom exceptions, perhaps use an InvalidOperationException
}
}
Failing that, if you don't actually need to abstract the functionality, don't catch the exception in GetFilenames at all, then call it like this:
try {
var list = GetFilenames()
DoSomething();
} catch (Exception e) {
DoSomethingElse();
}
I think you can make it simpler:
public void ICallGetFileNames()
{
var list = new List<YourObject>();
try
{
list = GetFileNames();
DoThisOtherMethod();
}
catch (Exception ex)
{
DoThisMethod();
}
}
This way, if the exception is thrown by your GetFileNames method, the DoThisOtherMethod() won't be called, since your code is going directly to the Exception block. Otherwise, if no exception is thrown, your code will call the DoThisOtherMethod just after the GetFileNames method.
The MessageBox.Show call below shows "Inner". Is this a bug?
private void Throw()
{
Invoke(new Action(() =>
{
throw new Exception("Outer", new Exception("Inner"));
}));
}
private void button1_Click(object sender, EventArgs e)
{
try
{
Throw();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message); // Shows "Inner"
}
}
I had a look at the reference source for System.Windows.Forms.Control, and the code that deals with Invoke looks like this:
try {
InvokeMarshaledCallback(current);
}
catch (Exception t) {
current.exception = t.GetBaseException();
}
GetBaseException:
public virtual Exception GetBaseException()
{
Exception inner = InnerException;
Exception back = this;
while (inner != null) {
back = inner;
inner = inner.InnerException;
}
return back;
}
So apparently it's like this by design. The comments in the source offer no explanation as to why they do this.
EDIT: Some site that is now gone claims this comment came from a guy at Microsoft:
Based on the winform comfirmation in the record, our analysis is
correct of the root cause and this behavior is intended. The reason was to
prevent the user from seeing too much of the Windows.Forms internal mechanisms.
This is because the winform's default error dialog also leverages Application.ThreadException to show the exception details. .Net Winform
team trims the other exceptions information so that the default error
dialog will not display all the details to the end user.
Also, some MSFTs have sugguested to change this behavior. However, .Net
Winform team thinks that changing the exception to throw is a breaking
change and for this reason WinForms will keep sending the innermost exception to the Application.ThreadException handler.
The OP doesn't seem to be interested in a work-around. Anyhow, this is mine:
public static object InvokeCorrectly(this Control control, Delegate method, params object[] args) {
Exception failure = null;
var result = control.Invoke(new Func<object>(() => {
try {
return method.DynamicInvoke(args);
} catch (TargetInvocationException ex) {
failure = ex.InnerException;
return default;
}
}));
if (failure != null) {
throw failure;
}
return result;
}
How is it possible to resume code execution after an exception is thrown?
For example, take the following code:
namespace ConsoleApplication1
{
public class Test
{
public void s()
{
throw new NotSupportedException();
string #class = "" ;
Console.WriteLine(#class);
Console.ReadLine();
}
}
public class Program
{
public static void Main(string[] args)
{
try
{
new Test().s();
}
catch (ArgumentException x)
{
}
catch (Exception ex)
{
}
}
}
}
After catching the exception when stepping through, the program will stop running. How can I still carry on execution?
EDIT: What I specifically mean is the line Console.WriteLine(#class); does not seem to be hit, because when I run to it when in debug mode, the program exits from debug mode. I want to run to this line and stop at it.
Thanks
Well, you don't have any code after the catch blocks, so the program would stop running. Not sure what you're trying to do.
The following should be proof that the program doesn't simply "stop" after the catch blocks. It will execute code after the catch blocks if there is code to be executed:
static void Main(string[] args)
{
try
{
new Test().s();
}
catch (ArgumentException x)
{
Console.WriteLine("ArgumentException caught!");
}
catch (Exception ex)
{
Console.WriteLine("Exception caught!");
}
Console.WriteLine("I am some code that's running after the exception!");
}
The code will print the appropriate string depending on the exception that was caught. Then, it will print I am some code that's running after the exception! at the end.
UPDATE
In your edit you asked why Console.WriteLine(#class); does not seem to be hit. The reason is that you are explicitly throwing an exception in the very first line of your s() method; anything that follows is ignored. When an exception is encountered, execution stops and the exception is propagated up the call stack until the appropriate handler can handle it (this may be a catch block that corresponds to the try that wraps the statement in question within the same method, or it may be a catch block further up the call-stack. If no appropriate handler is found, the program will terminate with a stacktrace [at least in Java - not sure if the same happens in C#]).
If you want to hit the Console.WriteLine line, then you shouldn't be explicitly throwing an exception at the beginning of the method.
It sounds like you're wanting resumeable exceptions. C# doesn't do resumeable exceptions, and I'm doubtful that CLR supports them.
The purpose of throwing an exception is to abort a function and an entire operation (call stack) if/when something in the call environment (parameters, object state, global state) makes the function's operation impossible or invalid. Passing a zero param to a function that needs to divide a quantity by that param, for example. Division by zero won't produce a meaningful result, and if that's the sole purpose of the function, then the function can't return a meaningful result either. So, throw an exception. This will cause execution to jump to the nearest catch or finally block on the call stack. There is no returning to the function that threw the exception.
If you want to step into your code in the debugger to trace the Console.WriteLine() calls, you need to remove the throw new NotSupportedException() line from your code and recompile.
If you're worried that an exception will be thrown in the method but you want the method to continue, add an error handler inside the method.
class Test
{
public void s()
{
try
{
// Code that may throw an exception
throw new NotSupportedException();
}
catch(Exception ex)
{
// Handle the exception - log?, reset some values?
}
string #class = "" ;
Console.WriteLine(#class);
Console.ReadLine();
}
}
You could also return a bool or some other value to indicate the state.
Disclaimer: I am not suggesting that you actually do this.
You can mimic the old VB style On Error Resume Next with the following code.
public static class ControlFlow
{
public static Exception ResumeOnError(Action action)
{
try
{
action();
return null;
}
catch (Exception caught)
{
return caught;
}
}
}
And then it could be used like the following.
public static void Main()
{
ControlFlow.ResumeOnError(() => { throw new NotSupportedException(); });
ControlFlow.ResumeOnError(() => { Console.WriteLine(); });
ControlFlow.ResumeOnError(() => { Console.ReadLine(); });
}
Some simple code I put together to catch exceptions that are thrown inside a catch block:
try
{
//do code here
}
catch (Exception ex)
{
try { SomeMethod1(); }
catch { }
try { SomeMethod2(); }
catch { }
try { SomeMethod3(); }
catch { }
}
finally
{
//cleanup goes here
}
Execution is still carying on but there is no code after the exception is caught. If you want to repeatedly call s then consider wrapping the try/catch block in a while loop.
The program stops running because there is no following code to be executed in the Main() method! You can add the following line to your code to keep the program running until there is a console input:
Console.ReadLine();
For that code, you can't. If you break the tasks up to smaller chunks, you can resume at the next chunk. But normally it's easier to have a different mechanism than exceptions to report non-fatal errors, such as a callback function which returns whether or not to continue.
You can use the "step-over" feature in debugging to achieve this on a per-run basis.
Instead of thowing the NotSupportedException, you could track that an exception was encountered, use a default value, and throw the exception at the end of the method call:
namespace ConsoleApplication1
{
public class Test
{
public void s()
{
bool exceptionEncountered = false;
if(someConditionNotSupported){//stub condition
exceptionEncountered=true
#class="DefaultValue";
}
Console.WriteLine(#class);
Console.ReadLine();
if(exceptionEncountered){
throw new NotSupportedException();
}
}
}
public class Program
{
public static void Main(string[] args)
{
try
{
new Test().s();
}
catch (ArgumentException x)
{
}
catch (Exception ex)
{
}
}
}
}
public static void Main()
{
for (int j = 0; j <= 100000; j++)
{
try
{
// TODO: Application logic...
}
catch
{
System.Threading.Thread.Sleep(1000);
}
}
}
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.
I have a recursive method call. When any exception is thrown, I would like to see, where in the recursive call stack it happened. I have a field which holds a "path" which represents the recursion stack.
Now I would like to add the path information to any exception that could possibly be thrown in the recursive call.
void Recursive(int x)
{
// maintain the recursion path information
path.Push(x);
try
{
// do some stuff and recursively call the method
Recursive(x + 6);
}
catch(Exception ex)
{
if (ex is RecursionException)
{
// The exception is already wrapped
throw;
}
// wrap the exception, this should be done only once.
// save the path and original exception to the wrapper.
throw new RecursionException(path.ToString(), ex);
}
finally
{
// maintain the recursion path information
path.Pop()
}
}
It just looks too complicated. There is not only one method. There are probably twenty or even more places where I had to write this code.
Is there any simpler way to implement this?
Edit: To point this out: I would like to have a much simpler situation where there is not such an overhead to recursively call the method, because I have many such recursive calls, there is not only one method, there are a couple of methods recursively calling each other, which is complex enough.
So I would like to avoid the whole try - catch block, but I can't see any solution for this.
It is not a big problem for Exceptions thrown in my own code, because it could include the path from the beginning. But it is a problem with every other exception.
Edit: The Exceptions need to be wrapped in any other code, not only when calling the recursive method:
try
{
int a = 78 / x; // DivisionByZeroExeption
Recursive(x + 6);
this.NullReference.Add(x); // NullReferenceException
}
So wrapping only the call to Recusive does not work.
there are many such methods, having different signatures, doing different things, the only common thing is the exception handling.
Just simplifying (slightly) the exception handling:
void Recursive(int x)
{
// maintain the recursion path information
path.Push(x);
try
{
// do some stuff and recursively call the method
Recursive(x + 6);
}
catch( RecursionException )
{
throw;
}
catch( Exception )
{
throw new RecursionException(path.ToString(), ex);
}
finally
{
// maintain the recursion path information
path.Pop()
}
}
You get callstack info in with Exception if that's of any use to you, beyond that you could write this as a snippet then just insert that where you need to for re-usability.
There's also the following possibility, which would be slow but should work:
void DoStuff()
{
this.Recursive(1, this.RecursiveFunction1);
this.Recursive(2, this.RecursiveFunction2);
}
bool RecursiveFunction1(int x)
{
bool continueRecursing = false;
// do some stuff
return continueRecursing;
}
bool RecursiveFunction2(int y)
{
bool continueRecursing = false;
// do some other stuff here
return continueRecursing;
}
private void Recursive(int x, Func<int, bool> actionPerformer)
{
// maintain the recursion path information
path.Push(x);
try
{
// recursively call the method
if( actionPerformer(x) )
{
Recursive(x + 6, actionPerformer);
}
}
catch( RecursionException )
{
throw;
}
catch( Exception ex )
{
throw new RecursionException(path.ToString(), ex);
}
finally
{
// maintain the recursion path information
path.Pop();
}
}
What about yanking the catch handler out of the recursive function and just writing the recursion without less of the handling?
void StartRecursion(int x)
{
try
{
path.Clear();
Recursive(x);
}
catch (Exception ex)
{
throw new RecursionException(path.ToString(), ex);
}
}
void Recursive(int x)
{
path.Push(x);
Recursive(x + 6);
path.Pop();
}
void Main()
{
StartRecursion(100);
}
Your problem is in the exception handling. Wrapping an exception in your own exception is generally a bad idea because it puts a burden upon the caller of your code to have to handle your exception. A caller that suspects that they might, say, be causing a "path not found" exception by calling your code cannot wrap their call in a try-catch which catches IOException. They have to catch your RecursionException and then write a bunch of code to interrogate it to determine what kind of exception it really was. There are times when this pattern is justified, but I don't see that this is one of them.
The thing is, it's really unnecessary for you to use exception handling at all here. Here are some desirable aspects of a solution:
caller can catch whatever kinds of exception they want
in debug build, caller can determine information about what the recursive function was doing when an exception was thrown.
OK, great, if those are the design goals, then implement that:
class C
{
private Stack<int> path
#if DEBUG
= new Stack<int>();
#else
= null;
#endif
public Stack<int> Path { get { return path; } }
[Conditional("DEBUG")] private void Push(int x) { Path.Push(x); }
[Conditional("DEBUG")] private void Pop() { Path.Pop(); }
public int Recursive(int n)
{
Push(n);
int result = 1;
if (n > 1)
{
result = n * Recursive(n-1);
DoSomethingDangerous(n);
}
Pop();
return result;
}
}
And now the caller can deal with it:
C c = new C();
try
{
int x = c.Recursive(10);
}
catch(Exception ex)
{
#if DEBUG
// do something with c.Path
You see what we're doing here? We're taking advantage of the fact that an exception stops the recursive algorithm in its tracks. The last thing we want to do is clean up the path by popping in a finally; we want the pops to be lost on an exception!
Make sense?
I think you are trying to include the recursive path in the exception details so as to aid debugging.
What about trying this.
public void Recursive(int x)
{
try
{
_Recursive(x)
}
catch
{
throw new RecursionException(path.ToString(), ex);
clear path, we know we are at the top at this point
}
}
private void _Recursive(int x)
{
// maintain the recursion path information
path.Push(x);
_Recursive(x + 6);
//maintain the recursion path information
//note this is not in a catch so will not be called if there is an exception
path.Pop()
}
If you are using threading etc, you will may have to look at storing path in thread local storage.
If you don’t wish to force your caller to deal with RecursionException, you could make the “path” public so the caller can access it. (As par Eric Lippert later answer)
Or you could log the path to your error logging system when you catch the exception and then just re-throw the exception.
public void Recursive(int x)
{
try
{
_Recursive(x)
}
catch
{
//Log the path to your loggin sysem of choose
//Maybe log the exception if you are not logging at the top
// of your applicatoin
//Clear path, we know we are at the top at this point
}
}
This has the advantage that the caller does not need to know about the “path” at all.
It all comes down to what your caller needs, somehow I think you are the caller for this code, so there is no point us trying to 2nd guess what is needed at this level of deal.
void Recursive(int x)
{
// maintain the recursion path information
path.Push(x);
try
{
// do some stuff and recursively call the method
Recursive(x + 6);
}
finally
{
// maintain the recursion path information
path.Pop()
}
}
void Recursive2(int x)
{
try
{
Recursive(x);
}
catch()
{
// Whatever
}
}
That way you only handle once, if an exception raises Recursive2 handles it, the recursion is aborted.