Related
I know that in Java, if an exception is caught by a catch clause and its catch block throws an exception, control would pass throw the associated finally block (if any) before the thread is terminated. This does not appear to be the case in C#, however.
It is possible to almost mirror this behavior in C# is by putting a try-finally statement inside the try block of the try-catch statement with the catch block that throws the exception, but that would be a problem if, for example, the finally block is supposed to contain code that disposes a Stream Writer that is supposed to log the exception.
Is there a clean way to achieve java-like try-catch-finally exception handling behavior in C#?
Here's an update with the requested sample code:
StreamWriter writer = new StreamWriter("C:\\log.txt");
try
{
throw new Exception();
}
catch (Exception e)
{
writer.WriteLine(e.Message);
throw e;
}
finally
{
if (writer != null)
{
writer.Dispose();
}
}
Add that code to a console application, run it, let the re-thrown exception go unhandled, attempt to delete C:\log.txt. You won't be able to, because control never passed through the finally block. Also, if you add a breakpoint to some line inside the finally block you will see that it doesn't get hit. (I'm using VS2005).
As far as I know, the only way to force control to pass through the finally block is if the re-thrown exception is handled by the catch block of an enclosing try block (if you took the code above and placed it inside the try block of another try-catch statement).
If the exception is not caught and is allowed to terminate the application, as in the sample code I provided, control won't pass through the finally block.
In Java it would. In C#, at least based on what I have seen, it would not.
No, this is incorrect. C# will always execute the finally block, even after an exception is thrown/re-thrown from the catch block. See When is finally run if you throw an exception from the catch block?.
In the .NET Framework, when an exception occurs, the system will determine what if anything is going to catch that exception before any finally blocks execute. Depending upon various application settings, an attempt to throw an exception which will not be caught may kill the application instantly, without giving any finally blocks (or anything else) a chance to run.
If one wraps the Main method, as well as each thread, in
try
{
...
}
catch
{
throw;
}
then any exception which is thrown within the try block will get caught. Even though it will be immediately re-thrown, any nested finally blocks will execute before the catch. There are some cases where this is desirable behavior; there are other cases where one may wish to e.g. perform some special logging if an exception isn't going to be caught (in some cases, the information one wishes to log may be destroyed if the finally blocks get a chance to run first). Within C#, there isn't any way to vary one's actions based upon whether an exception is going to be caught, but in VB.NET there are some ways via which that can be done; a VB.NET assembly which makes calls to C# code can give that code a way of knowing whether any exceptions thrown by an inner method will propagate out to the vb.net wrapper without being caught.
This does not appear to be the case in C#, however.
Is this what you are looking for.
As already stated, the finally block will always run once the catch block has been executed.
Edit: I just tried the sample code provided by the OP in a console application and lo and behold, it did not hit the finally block and had an error of "An unhandled exception of type 'System.Exception' occurred in ConsoleApplication1.exe". This was truly puzzling (besides the part of re-throwing the same exception in an endless loop) so I did a little investimagation and this is what I found:
If a exception occurs the CLR traverses up the call stack looking for
a matching catch expression. If the CLR doen't finds a matching one,
or the Exception gets re thrown each time, the Exception bubbles out
of the Main() method. In that case Windows handles the Exception.
Event Handling of Console Applications is the easiest to understand,
because there is no special Handling by the CLR. The Exception is
leaving the Applications Thread if not caught. The CLR opens a window
asking for debug or exit the application. If the user chooses to
debug, the debugger starts. If the user chooses to close, the
Application exits and the Exception is serialized and written to the
console.
Moral of the story, do not re-throw the same exception from a catch block in a console application!.
I am using ASP.NET/C#.
Here is an example where I am updating some information in database using lambda expression.
try
{
using (var db = new DataClasses1DataContext())
{
var logSubGroup = db.sys_Log_Account_SubGroups
.SingleOrDefault(subGroup => subGroup.cSubGroupName.Equals(subGroupName));
logSubGroup.cRejectedBy = rejectedBy;
logSubGroup.dRejectedOn = DateTime.Now;
logSubGroup.cAuthorizedStatus = "Rejected";
db.SubmitChanges();
}
}
catch (Exception ex)
{
}
As you can see I am not doing anything inside catch() block.
I know this is a terrible way of using try catch.
Can anyone just help me to use try catch block in a correct manner.
I am just clueless as to what must come inside the catch block.
Any suggestions are welcome.
Don't use a try-catch block at all, unless you have a specific reason to catch a specific exception.
Instead, use one of the global exception handling methods (Application_Error in ASP.NET) to globally catch unhandled exceptions, show an error message and log the error.
As a general rule, there is no need to catch an exception if the code catching the exception cannot do something about the problem, then continue running correctly. In code like what you've presented, can you identify some action you could take within the catch block to restore the program to a state where you trust it to continue running? If not, then just let the exception bubble up the stack.
You should ideally handle the error so that your application can recover from it, at the very least though, you should log it. You should never just swallow it. Also, you shouldn't handle an exception that you don't expect or can't handle. For example, when opening a file, a FileNotFoundException can be expected and handled, for example by displaying a warning and letting the user pick another file.
Theoretically it's up to you to decide what kind of exception may occur inside your catch statement it's not totally wrong doing it this way of course if you are in the development phase I would highly not recommend doing try catch since you can miss some of the important exception that may occur and you would want to fix also in general you should include a message or an action that should occur if the exception or error was caught a message to the user can be notified that action did not executed well but ideally you have to let user know what went wrong so in this case better error handling is a way to go
Just a thing I've been thinking of for a while. Do I need to handle KeyNotFoundException by catching that specific exception or can I just use a "blank" catch like this:
try
{
//Code goes here
}
catch
{
}
Or do I have to do it like this:
try
{
//Code goes here
}
catch(Exception ex)
{
}
Or do I have to do it like this:
try
{
//Code goes here
}
catch(KeyNotFoundException ex)
{
}
The reason why I ask is that when I look at crash count at App Hub I have a lot of crashes related to "KeyNotFoundException" but I never experience any crashes in my app. Could this be the problem, that I don't catch the specific exception and that App Hub crash statistics classifies it as a crash even if the exception is handled?
EDIT:
Here are some screenshots of the App Hub crash statistics (Stack Trace). Does anyone know ehat in detail it means? It has to do with my background agent and that might be the reason for why I never experience any crashes in my app:
No, the marketplace is counting only unhandled exceptions, so your app does crash.
An empty catch or catching Exceptions are the most general catches (Every exception is derived from the Exception base class, so you're catching everything.), the critical code is somewhere you don't use try-catch. Based on the exception you should check your dictionaries and think about what are the conditions which can cause error.
Generally a good practice is to check the correctness of parameters in your public methods so if any problem occurs you can provide yourself more helpful error messages, for example:
public User GetUser(string username)
{
if (String.IsNullOrEmpty(username))
throw ArgumentNullException("username");
return this.users[username];
}
In this case if things goes wrong you will see that you used a null for username, otherwise you would see a KeyNotFoundException. Hope this helps, good luck!
You can use a base exception to catch a more derived exception, so Exception will catch KeyNotFoundException because the latter inherits the former. So strictly speaking, if you want to catch "any" exception, catch (Exception) will suffice.
However, you should only catch exceptions if you can handle them in some meaningful manner. Though I'm not sure how this mindset stacks up against WP development.
As for your underlying problem, I've no idea. Does the App Hub not provide any details around the crash such as stack traces?
Your best bet is to leave the template code in place that registers for the unhandled exceptions event and put some logging into your application to record as much detail as you can about the state of the app during the crash.
No, you do not have to catch each specific exception type in a try / catch block, see the C# language reference.
However, rather than wrapping all your code in try / catch blocks, you probably want to add exception handling logic and logging into a handler for the Application.UnhandledException event. See this excellent blog post for an example of how to handle this event.
If you are interested in a specific exception, such as KeyNotFoundException in a particular part of the code then you catch it like this
try
{
//Code goes here
}
catch(KeyNotFoundException ex)
{
}
If you want to catch a specific exception and some undefined one you do something like this
try
{
//Code goes here
}
catch(KeyNotFoundException ex)
{
}
catch(Exception ex)
{
}
If you want to make sure your application doesn't crash use Collin's example with the Application.UnhandledException event.
You can catch all exceptions by catching the base class, but whether you want to depends on what your trying to achieve.
Generally speaking, you should only catch an exception at a level at which you have the knowledge to decide what should be done about the error, ie roll back some action, or display a message to the user. It is often the case that at a certain level it makes sense to catch a specific exception type, as that level of code understands what that means, but it may not make sense to catch all.
Avoid catching everything too soon, exceptions exist to tell you somethings wrong, blanket catching ignores that and can mean your program keeps running, but starts behaving wrong, possibly corrupting data. Its often better to "fail early and fail fast" when receiving unexpected exceptions.
As others have said - No - you dont need to catch the specific exception, catching Exception or just catch will prevent the exception from bubbling up.
However you should just catch specific exceptions where possible to make your code more explicit in what it is doing. Better again test for correctness before the potential error condition - again this is covered in other posts.
For your specific problem the link you posted seems to indicate that it is a problem with reading values from the isolated storage (IsolatedStorage.get_Item) - so wherever you access IsolatedStorage during from the ScheduledTaskAgent invocation you need to ensure the item exists before getting it. Perhaps there are some config settings missing or something?
Disclaimer, I'm from a Java background. I don't do much C#. There's a great deal of transfer between the two worlds, but of course there are differences and one is in the way Exceptions tend to be thought about.
I recently answered a C# question suggesting that under some circstances it's reasonable to do this:
try {
some work
} catch (Exeption e) {
commonExceptionHandler();
}
(The reasons why are immaterial). I got a response that I don't quite understand:
until .NET 4.0, it's very bad to catch
Exception. It means you catch various
low-level fatal errors and so disguise
bugs. It also means that in the event
of some kind of corruption that
triggers such an exception, any open
finally blocks on the stack will be
executed, so even if the
callExceptionReporter fuunction tries
to log and quit, it may not even get
to that point (the finally blocks may
throw again, or cause more corruption,
or delete something important from the
disk or database).
May I'm more confused than I realise, but I don't agree with some of that. Please would other folks comment.
I understand that there are many low level Exceptions we don't want to swallow. My commonExceptionHandler() function could reasonably rethrow those. This seems consistent with this answer to a related question. Which does say "Depending on your context it can be acceptable to use catch(...), providing the exception is re-thrown." So I conclude using catch (Exception ) is not always evil, silently swallowing certain exceptions is.
The phrase "Until .NET 4 it is very bad to Catch Exception" What changes in .NET 4? IS this a reference to AggregateException, which may give us some new things to do with exceptions we catch, but I don't think changes the fundamental "don't swallow" rule.
The next phrase really bothers be. Can this be right?
It also means that in the event
of some kind of corruption that
triggers such an exception, any open
finally blocks on the stack will be
executed (the finally blocks may
throw again, or cause more corruption,
or delete something important from the
disk or database)
My understanding is that if some low level code had
lowLevelMethod() {
try {
lowestLevelMethod();
} finally {
some really important stuff
}
}
and in my code I call lowLevel();
try {
lowLevel()
} catch (Exception e) {
exception handling and maybe rethrowing
}
Whether or not I catch Exception this has no effect whatever on the excution of the finally block. By the time we leave lowLevelMethod() the finally has already run. If the finally is going to do any of the bad things, such as corrupt my disk, then it will do so. My catching the Exception made no difference. If It reaches my Exception block I need to do the right thing, but I can't be the cause of dmis-executing finallys
For the question #2:
The author meant "Corrupted State Exceptions". They will be introduced in .NET 4.0 (CLR team announced this at PDC 2008 in this talk).
Corrupted state exceptions cannot be caught by normal catch block. Examples: Access violation, Invalid Memory.
But you might want to catch these exceptions:
In main() – write to log, exit, turn off addin
Very rare cases when you know that code throws exception like this (e.g. some cases with interop with native code)
To do this you should put attribute [HandleProcessCorruptedStateException] at the method where you want to catch CorruptedStateException.
To read more about these exceptions please see this MSDN article.
As a general rule you shouldn't catch exceptions unless:
You have a specific exception that you can handle and do something about. However in this case you should always check whether you shouldn't be trying to account for and avoid the exception in the first place.
You are at the top level of an application (for instance the UI) and do not want the default behaviour to be presented to the user. For instance you might want an error dialog with a "please send us your logs" style message.
You re-throw the exception after dealing with it somehow, for instance if you roll back a DB transaction.
Your finally blocks always execute. Your code sample is correct - the low level method should just have try and finally. For instance an unmanaged call might know that it needs to dispose of the unmanaged resource, but this wouldn't be exposed to .Net methods calling it. That call should get rid of the unmanaged resource in its finally block, and calling managed methods can handle exceptions or just pass them on up.
If there's something in an exception that you need to handle you should re-throw the exception, for instance:
try {
conn.BeginTransaction();
//do stuff
conn.CommitTransaction();
}
catch (Exception) {
conn.RollbackTransaction(); //required action on any exception
throw; //re-throw, don't wrap a new ex to keep the stack trace
}
finally {
conn.Dispose(); //always dispose of the resource
}
My motto is handle what you can (or need to) and let any other exceptions bubble up and catch them in an UnhandledException event.
You are correct tho, a finally block is always called (even in the event of an exception being raised in the try section) before you exit the method. So whether you want to the catch the exception on the out method or not is entirely up to you.....this should not affect the finally block being called.
Just to your third question:
If you have
nastyLowLevel() {
doSomethingWhichMayCorruptSomethingAndThrowsException();
}
MyEvilCatcher() {
try {
nastyLowLevel();
} catch (Exception e) {
MyExceptionHandler(e);
}
}
WiseCatcher() {
try {
MyEvilCatcher();
} catch (LowLevelException e) {
DoSomethingWiseSoFinnalyDontRuinAnything();
} finally {
DoSomethingWhichAssumesLowLevelWentOk();
}
}
I think the response you asked about just meant that some low level methods could use exceptions to inform some outer method that special care has to be taken. If you forget about this exceptions in your catch-all-handler and don't rethrow them, something might go wrong.
Generally, I prefer thinking carefully about which exceptions can possibly be thrown and catch them explicitely. I only use "generic handler" at the very outer level in production environments in order to log unexpected exception and present them to the customer in an well-formatted manner (including a hint to send us the log file.)
I think the quoted response is wrong (or maybe meant 2.0 instead of 4.0)? It sounds kinda bogus to me.
Take this code:
using System;
namespace OddThrow
{
class Program
{
static void Main(string[] args)
{
try
{
throw new Exception("Exception!");
}
finally
{
System.Threading.Thread.Sleep(2500);
Console.Error.WriteLine("I'm dying!");
System.Threading.Thread.Sleep(2500);
}
}
}
}
Which gives me this output:
Unhandled Exception: System.Exception: Exception!
at OddThrow.Program.Main(String[] args) in C:\Documents and Settings\username
\My Documents\Visual Studio 2008\Projects\OddThrow\OddThrow\Program.cs:line 14
I'm dying!
My question is: why does the unhandled exception text occur before the finally's? In my mind, the finally should be excuted as the stack unwinds, before we even know that this exception is unhandled. Note the calls to Sleep() - these occur after the unhandled exception is printed, as if it was doing this following:
Unhandled exception text/message
Finally blocks.
Terminate application
According to the C# standard, §8.9.5, this behaviour is wrong:
In the current function member, each try statement that encloses the throw point is examined. For each statement S, starting with the innermost try statement and ending with the outermost try statement, the following steps are evaluated:
If the try block of S encloses the throw point and if S has one or more catch clauses, the catch clauses are examined in order of appearance to locate a suitable handler for the exception. The first catch clause that specifies the exception type or a base type of the exception type is considered a match. A general catch clause (§8.10) is considered a match for any exception type. If a matching catch clause is located, the exception propagation is completed by transferring control to the block of that catch clause.
Otherwise, if the try block or a catch block of S encloses the throw point and if S has a finally block, control is transferred to the finally block. If the finally block throws another exception, processing of the current exception is terminated. Otherwise, when control reaches the end point of the finally block, processing of the current exception is continued.
If an exception handler was not located in the current function member invocation, the function member invocation is terminated. The steps above are then repeated for the caller of the function member with a throw point corresponding to the statement from which the function member was invoked.
If the exception processing terminates all function member invocations in the current thread, indicating that the thread has no handler for the exception, then the thread is itself terminated. The impact of such termination is implementation-defined.
Where am I going wrong? (I've got some custom console error messages, and this is in-the-way. Minor, just annoying, and making me question the language...)
The standard's statements about the order of execution are correct, and not inconsistent with what you are observing. The "Unhandled exception" message is allowed to appear at any point in the process, because it is just a message from the CLR, not actually an exception handler itself. The rules about order of execution only apply to code being executed inside the CLR, not to what the CLR itself does.
What you've actually done is expose an implementation detail, which is that unhandled exceptions are recognised by looking at a stack of which try{} blocks we are inside, rather than by actually exploring all the way to the root. Exceptions may or may not be handled by looking at this stack, but unhandled exceptions are recognised this way.
As you may be aware, if you put a top-level try{}catch{} in your main function, then you will see the behaviour you expect: each function's finally will be executed before checking the next frame up for a matching catch{}.
I could be way off base in the way I'm reading things...but you have a try finally block without a catch.
Juding by the description you posted, since the Exception is never caught, it bubbles up to the caller, works it's way up through the stack, is eventually unhandled, the call terminates, and then the finally block is called.
The output is actually from the default CLR exception handler. Exception Handlers occur before the finally block. After the finally block the CLR terminates because of the unhandled exception (it can't terminate before, as c# guarantees [1] that the finally clause is called).
So I'd say it's just standard behaviour, exception handling occurs before finally.
[1] guranteed during normal operation at least in absence of internal runtime errors or power outage
To add more into the mix, consider this:
using System;
namespace OddThrow
{
class Program
{
static void Main()
{
AppDomain.CurrentDomain.UnhandledException +=
delegate(object sender, UnhandledExceptionEventArgs e)
{
Console.Out.WriteLine("In AppDomain.UnhandledException");
};
try
{
throw new Exception("Exception!");
}
catch
{
Console.Error.WriteLine("In catch");
throw;
}
finally
{
Console.Error.WriteLine("In finally");
}
}
}
}
Which on my system (Norwegian) shows this:
[C:\..] ConsoleApplication5.exe
In catch
In AppDomain.UnhandledException
Ubehandlet unntak: System.Exception: Exception!
ved OddThrow.Program.Main() i ..\Program.cs:linje 24
In finally
Although not completely expected, the program does behave as it should. A finally block is not expected to be run first, it is only expected to be run always.
I adjusted your sample:
public static void Main()
{
try
{
Console.WriteLine("Before throwing");
throw new Exception("Exception!");
}
finally
{
Console.WriteLine("In finally");
Console.ReadLine();
}
}
In this case you will get the nasty unhandled exception dialog, but afterwards the console will output and wait for input, thus executing the finally, just not before windows itself catches the unhandled exception.
A try/finally without a catch will use the default handler which does exactly what you see. I use it all the time, e.g., in cases where handling the exception would be covering an error but there's still some cleanup you want to do.
Also remember that output to standard error and standard out are buffered.
The try-catch-finally blocks are working exactly as you expected if they are caught at some point. When I wrote a test program for this, and I use various nesting levels, the only case that it behaved in a way that matched what you described was when the exception was completely unhandled by code, and it bubbled out to the operating system.
Each time I ran it, the OS was what created the error message.
So the issue is not with C#, it is with the fact that an error that is unhandled by user code is no longer under the control of the application and therefore the runtime (I believe) cannot force an execution pattern on it.
If you had created a windows form application, and wrote all your messages to a textbox (then immediately flushing them) instead of writing directly to the console, you would not have seen that error message at all, because it was inserted into the error console by the calling application and not by your own code.
EDIT
I'll try to highlight the key part of that. Unhandled exceptions are out of your control, and you cannot determine when their exception handler will be executed. If you catch the exception at some point in your application, then the finally blocks will be executed before the lower-in-the-stack catch block.
To put a couple of answers together, what happens is that as soon as you have a Unhandled Exception a UnhandledExceptionEvent is raised on the AppDomain, then the code continues to execute (i.e. the finally). This is the MSDN Article on the event
Next try:
I believe this case isn't mentioned in the c# standard and I agree it seems to almost contradict it.
I believe the internal reason why this is happening is somewhat like this:
The CLR registers its default exception handler as SEH handler into FS:[0]
when you have more catches in your code, those handlers are added to the SEH chain. Alternatively, only the CLR handler is called during SEH handling and handles the CLR exception chain internally, I don't know which.
In your code when the exception is thrown, only the default handler is in the SEH chain. This handler is called before any stack unrolling begins.
The default exception handler knows that there are no exception handler registered on the stack. Therefore it calls all registered UnhandledException handler first, then prints its error message and marks the AppDomain for unloading.
Only after that stack unrolling even begins and finally blocks are called according the c# standard.
As i see it, the way the CLR handles unhandled exception isn't considered in the c# standard, only the order in which finallys are called during stack unrolling. This order is preserved. After that the "The impact of such termination is implementation-defined." clause takes effect.