This is code in my action handler:
private async void startButton_Click(object sender, EventArgs e)
{
try
{
var expression = expressionTextBox.Text;
var result = await Task.Run(() => Algebra.Divide(expression));
resultTextBox.Text = result.Polynom.ToString();
} catch (Exception ex)
{
Logger.Error(ex.Message);
detailsTextbox.BackColor = Color.Red;
detailsTextbox.AppendText("An error occurred! Please check if your expression is valid.");
}
}
And in Algebra.Divide I only put throwing exception for testing exception scenario:
public static DivisionResult Divide (string expression)
{
throw new Exception("Error occured");
}
And here is what happens when I click button:
Why doesn't it propagate exception to action handler where I have try/catch block? I tried also without synchronous call to Algebra.Divide() but it is the same error.
Simply said because your debugger is enabled. When you run the code without debugger it will be catched in your try catch block. You should get the behaviour you want when you press F5 when you see the exception. Put a breakpoint on your catch statement and you will see your program will continu running and will go to the catch statement.
You can also turn off the break on exception. You can do that like described here: How to turn off "Break when exception is thrown" for custom exception types
You are throwing Exception in a Task. So, Exception is throwing in different thread. Try look at that question: What is the best way to catch exception in Task?
Related
I have a method in which I'm checking if a file exists in my filesystem (UWP):
private async Task<bool> FileExistsAsync(string filename)
{
try
{
if (filename != null)
{
var item = await StorageFile.GetFileFromPathAsync(filename); // FileNotFoundException happens here
if (item != null)
return true;
}
return false;
}
catch (Exception e) // I Expect the debugger to handle the FileNotFoundException here, but it never happens
{
return false;
}
}
When I'm trying to get a non-existing file with StorageFile.GetFileFromPathAsync, I get an exception. For some reason it's not handled by my catch block, but looks like this instead:
What I've tried:
Explicitly handle a FileNotFoundException
Add a Try-catch-block inside of the if-statement
Note that the method needs to stay asynchronous because I have other stuff going on in this method which I removed in order to provide a Minimal, Complete, and Verifiable example.
Why is the debugger not entering my catch block when a FileNotFoundException is thrown?
In the Exception Popup i see [x] Break when this exception type is thrown. Try disabling it there, or from the Exception Settings dialog (Ctrl-Alt-E on my system, or menu Debug > Windows > Exception Settings).
var item = await StorageFile.GetFileFromPathAsync(filename);
Did you have try and catch in this function ?? if yes, add
throw
in catch
try this :Why can't I catch an exception from async code?
and this : Catch an exception thrown by an async method can help you.
I came across this new feature in C# which allows a catch handler to execute when a specific condition is met.
int i = 0;
try
{
throw new ArgumentNullException(nameof(i));
}
catch (ArgumentNullException e)
when (i == 1)
{
Console.WriteLine("Caught Argument Null Exception");
}
I am trying to understand when this may ever be useful.
One scenario could be something like this:
try
{
DatabaseUpdate()
}
catch (SQLException e)
when (driver == "MySQL")
{
//MySQL specific error handling and wrapping up the exception
}
catch (SQLException e)
when (driver == "Oracle")
{
//Oracle specific error handling and wrapping up of exception
}
..
but this is again something that I can do within the same handler and delegate to different methods depending on the type of the driver. Does this make the code easier to understand? Arguably no.
Another scenario that I can think of is something like:
try
{
SomeOperation();
}
catch(SomeException e)
when (Condition == true)
{
//some specific error handling that this layer can handle
}
catch (Exception e) //catchall
{
throw;
}
Again this is something that I can do like:
try
{
SomeOperation();
}
catch(SomeException e)
{
if (condition == true)
{
//some specific error handling that this layer can handle
}
else
throw;
}
Does using the 'catch, when' feature make exception handling faster because the handler is skipped as such and the stack unwinding can happen much earlier as when compared to handling the specific use cases within the handler? Are there any specific use cases that fit this feature better which people can then adopt as a good practice?
Catch blocks already allow you to filter on the type of the exception:
catch (SomeSpecificExceptionType e) {...}
The when clause allows you to extend this filter to generic expressions.
Thus, you use the when clause for cases where the type of the exception is not distinct enough to determine whether the exception should be handled here or not.
A common use case are exception types which are actually a wrapper for multiple, different kinds of errors.
Here's a case that I've actually used (in VB, which already has this feature for quite some time):
try
{
SomeLegacyComOperation();
}
catch (COMException e) when (e.ErrorCode == 0x1234)
{
// Handle the *specific* error I was expecting.
}
Same for SqlException, which also has an ErrorCode property. The alternative would be something like that:
try
{
SomeLegacyComOperation();
}
catch (COMException e)
{
if (e.ErrorCode == 0x1234)
{
// Handle error
}
else
{
throw;
}
}
which is arguably less elegant and slightly breaks the stack trace.
In addition, you can mention the same type of exception twice in the same try-catch-block:
try
{
SomeLegacyComOperation();
}
catch (COMException e) when (e.ErrorCode == 0x1234)
{
...
}
catch (COMException e) when (e.ErrorCode == 0x5678)
{
...
}
which would not be possible without the when condition.
From Roslyn's wiki (emphasis mine):
Exception filters are preferable to catching and rethrowing because
they leave the stack unharmed. If the exception later causes the stack
to be dumped, you can see where it originally came from, rather than
just the last place it was rethrown.
It is also a common and accepted form of “abuse” to use exception
filters for side effects; e.g. logging. They can inspect an exception
“flying by” without intercepting its course. In those cases, the
filter will often be a call to a false-returning helper function which
executes the side effects:
private static bool Log(Exception e) { /* log it */ ; return false; }
… try { … } catch (Exception e) when (Log(e)) { }
The first point is worth demonstrating.
static class Program
{
static void Main(string[] args)
{
A(1);
}
private static void A(int i)
{
try
{
B(i + 1);
}
catch (Exception ex)
{
if (ex.Message != "!")
Console.WriteLine(ex);
else throw;
}
}
private static void B(int i)
{
throw new Exception("!");
}
}
If we run this in WinDbg until the exception is hit, and print the stack using !clrstack -i -a we'll see the just the frame of A:
003eef10 00a7050d [DEFAULT] Void App.Program.A(I4)
PARAMETERS:
+ int i = 1
LOCALS:
+ System.Exception ex # 0x23e3178
+ (Error 0x80004005 retrieving local variable 'local_1')
However, if we change the program to use when:
catch (Exception ex) when (ex.Message != "!")
{
Console.WriteLine(ex);
}
We'll see the stack also contains B's frame:
001af2b4 01fb05aa [DEFAULT] Void App.Program.B(I4)
PARAMETERS:
+ int i = 2
LOCALS: (none)
001af2c8 01fb04c1 [DEFAULT] Void App.Program.A(I4)
PARAMETERS:
+ int i = 1
LOCALS:
+ System.Exception ex # 0x2213178
+ (Error 0x80004005 retrieving local variable 'local_1')
That information can be very useful when debugging crash dumps.
When an exception is thrown, the first pass of exception handling identifies where the exception will get caught before unwinding the stack; if/when the "catch" location is identified, all "finally" blocks are run (note that if an exception escapes a "finally" block, processing of the earlier exception may be abandoned). Once that happens, code will resume execution at the "catch".
If there is a breakpoint within a function that's evaluated as part of a "when", that breakpoint will suspend execution before any stack unwinding occurs; by contrast, a breakpoint at a "catch" will only suspend execution after all finally handlers have run.
Finally, if lines 23 and 27 of foo call bar, and the call on line 23 throws an exception which is caught within foo and rethrown on line 57, then the stack trace will suggest that the exception occurred while calling bar from line 57 [location of the rethrow], destroying any information about whether the exception occurred in the line-23 or line-27 call. Using when to avoid catching an exception in the first place avoids such disturbance.
BTW, a useful pattern which is annoyingly awkward in both C# and VB.NET is to use a function call within a when clause to set a variable which can be used within a finally clause to determine whether the function completed normally, to handle cases where a function has no hope of "resolving" any exception that occurs but must nonetheless take action based upon it. For example, if an exception is thrown within a factory method which is supposed to return an object that encapsulates resources, any resources that were acquired will need to be released, but the underlying exception should percolate up to the caller. The cleanest way to handle that semantically (though not syntactically) is to have a finally block check whether an exception occurred and, if so, release all resources acquired on behalf of the object that is no longer going to be returned. Since cleanup code has no hope of resolving whatever condition caused the exception, it really shouldn't catch it, but merely needs to know what happened. Calling a function like:
bool CopySecondArgumentToFirstAndReturnFalse<T>(ref T first, T second)
{
first = second;
return false;
}
within a when clause will make it possible for the factory function to know
that something happened.
I have a sync function such as the following function that generate an IO error (I delete the detail to make it simple):
public override void SyncFunction()
{
throw new IOException("test");
}
and I used it in this way:
try
{
await Task.Run(() => this.SyncFunction());
}
catch (Exception ex)
{
MessageBox.Show("Error:"+Environment.NewLine + ex.Message);
}
But when I run the application, the catch block doesn't get called, but I am getting a message that application crashed. What is the problem and how can I fix it?
The code as you described it should handle the exception just fine.
However, the thing that would crash your application is an exception thrown inside an async void method as the exception has no Task to be stored inside.
So, my guess is that SyncFunction actually looks more like this:
public override async void SyncFunction()
{
throw new IOException("test");
}
And when you invoke it the exception is posted to a ThreadPool thread and that crashes the application.
If that's the case, don't use async void unless in a UI event handler and make sure you handle such exceptions by registering to the AppDomain.CurrentDomain.UnhandledException event.
I'm having an issue with a try/catch block, but I can't seem to find out exactly how try/catch works when it's running that I think might have my answer. I have the following try/catch block:
try
{
...
}
catch (MyException e)
{
Log.Error("oh no!");
throw;
}
Now when I run this code I'm getting a System.TypeLoadException: Could not load type SDK.MyException from assembly "SDKSampleLibrary, Version... etc error.
I'm wondering 2 things. First, when does the computer check to see if MyException is there. Is it when it gets to the try or when it gets to the catch? Second, the SDKSampleLibrary.dll is there. How do I tell why it's not seeing it?
If the class MyException gets thrown within the try area, it will get handled inside the catch, See my example below where i throw a new exception which would get handled by the catch statement. However any other kinds of exceptions would not be handled/
try
{
throw(new MyException()); // handled by the catch
throw(new ParseException()); //not handled.
int test = "test" //not handled
}
catch (MyException e)
{
Log.Error("oh no!");
throw;
}
can also catch general exceptions to catch ALL exceptions like:
try
{
throw(new MyException()); // handled by the catch
throw(new ParseException()); //handled.
int test = "test" //handled
}
catch (Exception e)
{
Log.Error("oh no!");
throw;
}
The compiler sees the class since it is blue and does not give compile errors. The problems is happening when you are running the code. I think the problem is in de code that throws the exception which cannot create it. You could try to use the normal Exception type in the catch block and then set a break point.
The problem is not with the try/catch block but rather the problem is the type of exception that you are trying to catch as specified by the exception that your code is throwing. This exception occurs when the runtime tries to load the MyException object. You should make sure that the MyException inherits either from the Exception base class or from any of its children.
I`m writing class. Here is one of functions:
public string GetAttribute(string attrName)
{
try
{
return _config.AppSettings.Settings[attrName].Value;
} catch(Exception e)
{
throw new ArgumentException("Element not exists", attrName);
return null;
}
}
Then, I am using it in the main form MessageBox.Show(manager.GetAttribute("not_existing_element"));
Visual Studio throws an Exception at line:throw new ArgumentException("Element not exists", attrName);
but, I am want to get an Exception at line MessageBox.Show(manager.GetAttribute("not_existing_element"));
How can I do that?
P.S: Sorry for bad English.
You are misusing exception handling. In your code, if you get (for example) a NullReferenceException, you will catch it and then throw an ArgumentException.
Rewrite your method to not have any exception handling:
public string GetAttribute(string attrName)
{
return _config.AppSettings.Settings[attrName].Value;
}
This way, you are not resetting the stack trace and swallowing the original exception.
In terms of getting an exception on the calling line - you will never be able to get an exception at a line that isn't throwing an exception.
A couple of things:
First, you'll get an unreachable code warning for the return null statement in your catch, because the throw will execute before the return. You can simply delete the return null statement.
Secondly, I'm not sure what you mean by getting the exception at the MessageBox line, but I think you mean you want to catch it there. Wrap the call to MessageBox in a try-catch.
try
{
MessageBox.Show(manager.GetAttribute("not_existing_element"));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}