I need some help on how to use try/catch correctly. In the following example I am using the Google Tasks API, but that's not the important thing.
So here's my current code:
try
{
// try something that could cause an exception
Task result = service.Tasks.Patch(body, listId, taskId).Execute();
}
catch (Google.GoogleApiException ex)
{
// handle exception
Debug.WriteLine("exception");
}
This code tries to do something and I am catching possible exceptions. Now instead of only outputting a message when an error occurs (in the catch block) I also want to output a message when everything is ok. I am not sure though, where to put such a message?
If I put a success message in a finally block, it's always displayed, even if there are errors
If I put a success message after try/catch and maybe finally, it's always displayed, even if there are errors
So, would I put a success message in the try block like this?
try
{
// try something that could cause an exception
Task result = service.Tasks.Patch(body, listId, taskId).Execute();
Debug.WriteLine("task updated successfully"); // <------------------ success message
}
catch (Google.GoogleApiException ex)
{
// handle exception
Debug.WriteLine("exception");
}
My understanding was that try contains only code that can fail and obviously Debug.WriteLine("task updated successfully"); is nothing that can fail, but still included in the try block. Please let me know if my understanding of a try block containing only code that can fail was wrong and if it's normal to include a success message in the try block or what is the best practice for my use case.
No, you don't have to only include code that can fail in the try block. You should also include code that requires that call to succeed. For example, if you need to connect to a database and run some queries you would do it all in the try block.
You might want to include a second catch block to catch other exceptions. Just a random thought.
Related
Scenario
I have a method that does database operation (let's say). If during that operation any exception is raised, I just want to throw that exception to the caller. I don't want to do any specific task in the catch block, assuming caller will do whatever it wants to do with that exception. In this scenario, which one is appropriate exception handling technique?
try
{
// Some work that may generate exception
}
catch(Exception)
{
throw;
}
finally
{
// Some final work
}
Is the above equivalent to the following try/catch/finally?
try
{
// Some work that may generate exception
}
catch
{
throw;
}
finally
{
// Some final work
}
Is the above equivalent to the following try/finally?
try
{
// Some work that may generate exception
}
finally
{
// Some final work
}
Which one is better than the other? Which one should be used?
No, they are not equivalent. They may be equivalent in some cases, but the general answer is no.
Different kinds of catch blocks
catch block with a specified exception type
The following will only catch managed exceptions that inherit from System.Exception and then executes the finally block, which will happen regardless of whether an exception was thrown or not.
try
{
// Some work that may generate exception
}
catch (Exception)
{
throw;
}
finally
{
// Some final work
}
catch block without a specified exception type
The following catch block without a type specifier will also catch non-managed exceptions that are not necessarily represented by a managed System.Exception object, and then executes the finally block, which will happen regardless of whether an exception was thrown or not.
try
{
// Some work that may generate exception
}
catch
{
throw;
}
finally
{
// Some final work
}
finally block without a catch block
If you do not have a catch block at all, your finally will still be executed regardless of whether or not an exception occoured.
try
{
// Some work that may generate exception
}
finally
{
// Some final work
}
When are they equivalent?
In case your catch block doesn't specify an exception and only contains the throw; statement, the last two are indeed equivalent. In case you don't care about non-managed exceptions and your catch block only contains the throw; statement, all three can be considered equivalent.
Notes
A note about throw
The following two pieces of code contain a subtle difference. The latter will re-throw the exception, meaning that it will rewrite the exception's stack trace, so these are definitely not equivalent:
catch (Exception e)
{
throw;
}
And
catch (Exception e)
{
throw e;
}
In case you use finally with an IDisposable, the following two pieces of code are almost equivalent, but with some subtle differences:
When the object is null, the using statement won't give you a NullReferenceException
When using the try-finally technique, the variable remains in scope, although it is very discouraged to use any object after it has been disposed. However you can still reassign the variable to something else.
Something obj = null;
try
{
obj = new Something()
// Do something
}
finally
{
obj.Dispose();
}
And
using (var obj = new Something())
{
// Do something
}
You have some good answers so far, but there is an interesting difference that they did not mention so far. Consider:
try { ImpersonateAdmin(); DoWork(); }
finally { RevertImpersonation(); }
vs
try { ImpersonateAdmin(); DoWork(); }
catch { RevertImpersonation(); throw; }
finally { RevertImpersonation(); }
Suppose DoWork throws.
Now the first question at hand is "is there a catch block that can handle this exception", because if the answer is "no" then the behaviour of the program is implementation-defined. The runtime might choose to terminate the process immediately, it might choose to run the finally blocks before it terminates the process, it might choose to start a debugger broken at the point of the unhandled exception, it might choose to do anything it likes. Programs with unhandled exceptions are permitted to do anything.
So the runtime starts looking for a catch block. There's none in this try statement, so it looks up the call stack. Suppose it finds one with an exception filter. It needs to know if the filter will permit the exception to be handled, so the filter runs before impersonation is reverted. If the filter accidentally or deliberately does something that only an admin can do, it will succeed! This might not be what you want.
In the second example, the catch catches the exception immediately, reverts the impersonation, throws, and now the runtime starts looking for a catch block to handle the re-throw. Now if there is a filter it runs after the impersonation is reverted. (And of course the finally then reverts again; I assume that reverting impersonation is idempotent here.)
This is an important difference between these two code snippets. If it is absolutely positively forbidden for any code to see the global state that was messed up by the try and cleaned up by the finally, then you have to catch before finally. "Finally" does not mean "immediately", it means "eventually".
Both of the try / catch statements are equivalent in that they are re-throwing the original exception that was caught. However the empty catch is more broad (as Venemo has already stated, catching unmanaged exceptions). If you are to catch an exception and capture it in a variable you can use it for logging or you can throw a new exception while passing the original exception as an argument - making it the "inner exception".
The finally is going to function the same regardless.
Which one should be used, in a scenario where we don't need logging exception and we explicitly assume caller will handle exception being raised like writing in file stream or sending email.
If the caller will handle the exception and you do not need to log the occurrence of the exception at this level, then you should not be catching at all. If the caller will handle an exception being thrown, there is no need to catch an exception just to re-throw it.
Valid reasons to catch an exception that will be re-thrown:
throw new Exception("WTF Happened", ex); // Use as inner exception
Log exception
Use a finally block to execute some cleanup code
I saw some code the other day in one of our projects that uses a try catch and re-throws the caught exception like this:
try
{
exceptionProneCode();
}
catch(Exception ex)
{
throw ex;
}
Nothing else was done with the exception in the catch block so I'm not even sure why it's re-thrown. I can't see any benefit to actually throwing the same exception again and doing nothing with the exception.
If you re-throw an exception that's caught in the catch block, how does C# handle this? Does it get stuck in an infinite throw/catch loop? Or does it eventually leave the try catch?
Consider these two models:
1- By re-throwing ex:
catch(Exception ex)
{
throw ex;
}
you loose StackTrace. If the exception is logged somewhere the StackTrace containing immediate frames of the call stack (history of method calls) is lost.
2- In contrast by throw:
catch(Exception ex)
{
// do something here
throw;
}
you maintain StackTrace. You can do additional processing and then re-throw the exception without loosing the trace string.
It continues to throw the exception up the calls stack. One thing that this piece of code does that is different from if you didn't catch the exception, it will reset the exception location (call stacks, line #, etc) to where you re-threw the exception, so you won't have the location where the original exception was thrown.
If you're not going to actually do something in the catch block I would recommend not catching, or at the very least rethrowing with just a throw instead of throw ex.
It throws the exception to the caller. But it handles it here so it doesn't throw an unhandled exception. However, honestly, I don't see the benefit of this. Just let it throw the exception. Why? Because an exception is only unhandled if the entire call stack above it doesn't have a try ... catch. This isn't doing anything useful.
Does it get stuck in an infinite throw/catch
loop? Or does it eventually leave the try catch?
No. Yes.
The code provides no benefit and does harm to debugging as noted by everyone else.
A good catch block will catch a specific expected issue and log & continue (the problem doesn't indicate the applications state is corrupt), log and halt (because the application is now in an unknown state and continuing could wreck more harm), do something else (e.g. fall back to an equivalent technology/algorithm), wait and try again.
The default is that something is unexpected, should be logged and the application should be stopped-- either abandoning the page or if a winforms app, revert back to a known state if possible.
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
I have a statement inside a try/catch block, but the exception is not getting caught. Can anyone explain?
Exception Details:
System.NullReferenceException: Object
reference not set to an instance of an
object.
Source Error:
Line 139: try
Line 140: {
Line 141: return (int)Session["SelectedLeadID"];
Line 142: }
Line 143: catch (Exception ex)
Update
This is an ASP.NET application. In the catch block, a new exception is thrown. The code you see is what is displayed on the ASP.NET error page.
That catch block should catch the exception, but make sure there's no re-throwing in there.
Another small comment: I've been tricked quite a few times by VS, cause it breaks on exceptions like that while running in debug-mode. Try to simply press 'continue' or 'F5' and see if your application doesn't work anyway :)
I suspect you're going to need to add more detail - that isn't reproducible just from your code. In particular (as already noted) we'd need to see inside the catch, and verify that the exception is actually being thrown from inside the try and not somewhere else.
Other possibilities:
you have dodgy code inside the exception handler that is itself throwing an exception
you have a dodgy Dispose() that is getting called (using etc)
you are in .NET 1.1 and the thing getting thrown (in code not shown) isn't an Exception, but some other object
If it is only the debugger breaking on the exception and you are using VS2005 or above, you might want to check under Debug->Exceptions... if any of the Common-Language-Runtime-Exceptions are activated. If so, the debugger will always catch the exceptions first, but you are allowed to continue.
To revert to normal execution, simply uncheck the apropriate exceptions from the list.
I also faced this problem
Image
which was solved by removing the tick of
"Break when this exception type is thrown."
Warning:
Of course, I am not aware of the consequences of this.
I've also had such an issue and it was driving me nuts for quite some time, but in the end I figured it out. It's quite stupid, but maybe it might help someone:
public IActionResult SomeFunction()
{
try
{
return Json(new ClassWhichTakes2Parameters("FirstParameter"), "SecondParameter"); //comma placed in the wrong spot
}
catch (Exception ex)
{
//some code
}
}
It should have looked like:
public IActionResult SomeFunction()
{
try
{
return Json(new ClassWhichTakes2Parameters("FirstParameter", "SecondParameter"));
}
catch (Exception ex)
{
//some code
}
}
Since I had many return statements in that function I didn't catch this right away.
Also, the error message I've been receiving wasn't quite what I have expected at first, but now it makes sense:
System.InvalidOperationException: Property
'JsonResult.SerializerSettings' must be an instance of type
'Newtonsoft.Json.JsonSerializerSettings'.
The code looks terribly ugly IMO. For there to be something in the catch() block means you are going to have another return ... statement which AFAIK you should always have a single return statement at the end of each function to make following code easier.
i.e. maybe your code should look like
public int Function()
{
int leadID = 0;
try
{
int leadID = (int)Session["SelectedLeadID"];
}
catch (Exception ex)
{
...
}
return leadID
}
Single exit points are supposed to make the code easier to follow, I guess? Anyway, to get any useful help you have to post more of the function.
I have the following code in a class of mine. The purpose of this class is to get the balance from a web server. Just in case something goes wrong with getting the balance. I will handle a exception. However, all this is easy to do. But I am left wondering what do I return in my catch statement.
Most of the examples I looked at just write to the console using:
Console.WriteLine(ex.Message);
That is all very well. But in a real application what do most developers do?
//Download only when the webclient is not busy.
if (!wc.IsBusy)
{
// Sleep for 1/2 second to give the server time to update the balance.
System.Threading.Thread.Sleep(500);
try
{
// Download the current balance.
wc.DownloadStringAsync(new Uri(strURL));
}
catch (WebException ex)
{
Console.Write("GetBalance(): " + ex.Message);
}
}
else
{
Console.Write("Busy please try again");
}
My function at the moment returns void. And I am just wondering what else I would return if the webclient is busy?
Many thanks for any advice,
Do not catch an exception if you cannot handle it. If you return just some value, the calling method has to check if the value is a real result or just an indicator of an exception. And now this method must decide what to do and return. And the method calling this method. And the method...
So just let the exception bubble up the stack and catch it somewhere where you can handle it. Maybe directly below the user interface and then display a message box asking if the user wants to retry or display information how to solve the problem. If you have no user interface, catch it somewhere where you can solve the problem and retry. If it is a temporary problem, retry the whole task at a reasonable level until the call succeeds.
If you want to log something, use the following pattern to log the exception an rethrow it.
try
{
DoStuff();
}
catch (Exception exception)
{
Log(exception.ToString());
throw;
}
Note that it is throw; and not throw exception;. If you do the later, you lose the original stack trace. If you can infer more details about the cause of the exception, you should wrap the caught exception into a more meaningful exception with additional information.
try
{
DoStuff();
}
catch (SpecificMeaninglessException exception)
{
Log(exception.ToString());
throw new MeaningfulException("Details about the error.", exception);
}
catch (Exception exception)
{
Log(exception.ToString());
throw;
}
You should use ex.ToString() method
Exception.Message
contains a simple description of the exception (e.g. "Object reference not set...").
Exception.ToString()
contains a description of the exception along with a complete stack trace.
Exception Handling Best Practices in .NET
You could re-run the method if the client is busy but wait a certain time before retries? Potentially with a failure after x retries.
If instead you wish to move on and simply log the problem, your catch statement could log the exception to a file-based log, event viewer, submit to a database, raise an alert (email, sms etc.) if it is necessary.
Depends on the severity of the exception.
I would suggest looking into The Exception Block from Patterns & Practices
If you're only interested in viewing the exception you should re throw the exception so who-ever is planning on handling it will still get it.
You certainly don't want to mask an unhandled exception. Let that bubble up through the stack. But if you are asking what to return if the web client is just busy, how about
returning either a random interval or some meaningful interval that the function caller should wait before attempting to download the balance again? A random number could distribute load or otherwise mitigate a collision problem. A more meaningful interval could be sent back based on the the current state of the server.