I couldn't think of a good way to test it myself so asking this question:
Lets say I have a list of transactions that I have sending them one by one to a web service and the result of webservice call may be Success, Failed or something weird may have happened and it just crashes.
So the overall code I have is like this:
for each (transaction)
{
try
{
string result = webservice.Call(transaction);
if result == "Faild"
{
// log some errors.
}
}
catch (Exception ex)
{
// Log some errors, stack trace, etc...
}
}
So my question is: if it falls into an exception for one of the transaction calls, then does the whole thing stop? OR it will get out of the exception block and will move on to next item in the for-each?
A catch is a catch and will do what a catch is supposed to do.
The loop will not break unless you rethrow the exception.
If you want to complete the entire loop before telling the user that something went wrong you can do
something like this:
List<Exception> exceptions = new List<Exception>();
foreach (var transaction in transactions)
{
try
{
string result = webservice.Call(transaction);
if result == "Faild"
{
// log some errors.
}
}
catch (Exception ex)
{
exceptions.Add(ex);
}
}
if (exceptions.Any())
throw new AggregateException(exceptions);
It WILL continue looping until you have no more transactions to loop through. That's what is so useful about try catch.
Since the try/catch is inside the loop, it will run for each transaction call.
If you had put the loop inside the try, then it would blow up at the first exception.
Check out the information here on using try { ... } catch() { ... } finally { ... }, where you can have code that executes after the exception is handled.
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.
Consider such a function:
void RequestThings(List<Things> container, Connection connection, Int32 lastVersion) {
var version = lastVersion;
try {
foreach(var thing in connection.RequestThings(version)) {
container.Add(thing);
version = thing.lastVersion;
}
}
catch(Exception ex) {
RequestThings(container, connection, version + 1);
}
}
But this choice is far not perfect: it involves adding to a recursion depth (up to a stack overflow) in case if there are (many) exceptions.
How do I rewrite this the iterative way?
I've tried to do this like:
var container = new List<Things>();
var version = getLastVersionFromDB();
foreach(var thing in connection.RequestThings(version)) {
try {
container.Add(thing);
}
catch(Exception ex) {
continue;
}
}
But it appears that exception doesn't get handled. How do I do this?
edit. the details
Connection.RequestThings(Int32 startVersion) requests data from a remote server. Accepts a seed version as its only parameter. There might be blocked/damaged documents which you cannot request though they appear on the results returned by calls to Connection.RequestThings(Int32 startVersion). This piece throws the exception
Don't know why but the inner try/catch in my iterative example doesn't catch the exception.
Generally, it's a bad idea to have a catch clause for all exceptions. Consider catching only a specific exception type to be sure that you're not swallowing unexpected errors.
Additionally, if you got a stack overflow in the first place, it indicates that you might be doing something wrong. For example, what happens if you pass an invalid version number to this method, and there are no documents with a larger version number available? This method will keep running forever, with no chance to gracefully cancel it. Especially since it seems that you are getting the "last version" from a database somehow; if this fails, you can be pretty certain that no higher version exists.
Having said that, you can simplify the method by creating an "infinite" loop and then using return to exit the method on success:
void RequestThings(List<Things> container, Connection conn, int version)
{
while (true)
{
try
{
foreach (var thing in connection.RequestThings(version))
{
container.Add(thing);
version = thing.lastVersion;
}
return;
}
catch (Exception ex)
{
Log.Error(ex);
version++;
}
}
}
A slightly better approach might be to make sure that you really get the entire list on success, or nothing. The way your code is written right now leaves the possibility of container being filled multiple times if an exception happens while iterating.
List<Things> RequestThings(Connection conn, int version)
{
while (true)
{
try
{
// this will either create an entire list,
// or fail completely
return connection.RequestThings(version).ToList();
}
catch (Exception ex)
{
Log.Error(ex);
version++;
}
}
}
I know, we can use try-catch block to handle exceptions. But I have some doubts in the usage of Try-Catch.
What is the difference between
try
{
//Some code
}
catch
{
}
and
try
{
//Some code
}
catch(Exception)
{
}
and
try
{
//Some code
}
catch(Exception oops)
{
}
In my program, I need to catch all exceptions and I don't want to log them. From the above mentioned Try-Catch blocks, which should be used?
Using a catch without a parameter is no longer useful as of framework 2.0, as all unmanaged exceptions are wrapped in a managed exception. Before that you could use it to catch exceptions thrown by unmanaged code.
You can specify just the type of the exception if you don't want to use any information from it, but usually you would want a name for it so that you can get to the information:
try {
// some code
} catch(Exception) {
// i don't care about any information in the Exception object, just the type
}
vs.
try {
// some code
} catch(Exception ex) {
// use some information from the exception:
MessageBox.Show("Internal error", ex.Message);
}
You should always try to have an exception type that is as specific as possible, as that makes it easier to handle the exception. Then you can add less specific types to handle other exceptions. Example:
try {
// some database code
} catch(SqlException ex) {
// something in the database call went wrong
} catch(Exception ex) {
// something else went wrong
}
So far you use catch (Exception), the first and the second are the same. You catch everything in this case. When you like to catch a specific exception like UnauthorizedAccessException, you have to use the second one like this:
try
{
//Some code
}
catch (UnauthorizedAccessException)
{
MessageBox.Show(oops.Message);
}
In the third case you can use the Exception through the variable oops.
For example:
try
{
//Some code
}
catch (Exception oops)
{
MessageBox.Show(oops.Message);
}
Or with a specific exception:
try
{
//Some code
}
catch (UnauthorizedAccessException oops)
{
MessageBox.Show(oops.Message);
}
Generic try catch, this will catch any type of exception
try
{
//Some code
}
catch
{
}
This will catch the specific type of exception that you specify, you can specify multiple.
try
{
}
catch (UnauthorizedAccessException)
{
}
This will do the same as above but give you a variable that has access to the properties of an exception.
try
{
}
catch (UnauthorizedAccessException ex)
{
}
You should be using the last one, and handling in a clean way your exception.
The first too way are the same but are "Eating Exceptions", witch is the worst thing to do.
At least log your exception!
Your first and second example are the same. They will both catch any exception, without any information about the exception. The third exception stores the exception in oops, which you can then use to get more information about the exception.
Look at msdn documentation: http://msdn.microsoft.com/en-us/library/vstudio/0yd65esw.aspx
The best is specify which kind of errors you would like catch.
The third one is the best...
You can catch any kind of specific exception and it will be precise... This helps in identifying the exact exception and easy for us to correct them as well
For eg: one can catch DivisionByZeroException, TargetInvocationException, ArrayOutOfBoundException, etc...
They are all pretty much the same (I assume the first is shorthand for writing the 2nd), the difference with the last is you are putting the exception object into a variable so you can use it in the catch.
Usually when I see code like this I tend to worry as it's generally not a good idea as you could be masking bigger problems with your application.
Rule of thumb - handle what you can, let everything else bubble up.
i think it has the same function - To trace where the error is set/ or where did something get wrong,
using try-catch this way
> try {
//some codes
}
catch
{
//anything
//e.g.:
MessageBox.Show("Something is wrong!");
}
this tells the that there is something wrong but didn't show the detailed report. (Clever way to hide some errors is don't put anything in the catch{} xD, but this is not advised to do)
the next is to show detailed report of the error
try
{
//some codes
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
hope this helps! :D
How to correctly let an exception to bubble up?
If I use Try-Catch when calling a method, is just throwing an exception inside a method like not trying to catch it at all?
For illustration: Are these approaches do the same work?
Example 1:
try
{
MyFileHandlingMethod();
}
catch (IOException ex)
{
string recfilepath = "...
string rectoadd = "RecDateTime=" + DateTime.Now.ToString()+ ...+ex.Message.ToString();
File.AppendAllText(recfilepath, rectoadd);
}
catch (exception)
{
throw;
}
...
MyFileHandlingMethod()
{
...
TextReader tr2 = new StreamReader(nfilepath);
resultN = tr2.ReadLine();
tr2.Close();
...
}
Example 2:
try
{
MyFileHandlingMethod();
}
catch (IOException ex)
{
string recfilepath = "...
string rectoadd = "RecDateTime=" + DateTime.Now.ToString()+ ...+ex.Message.ToString();
File.AppendAllText(recfilepath, rectoadd);
}
catch (exception)
{
throw;
}
...
MyFileHandlingMethod()
{
...
try
{
TextReader tr2 = new StreamReader(nfilepath);
resultN = tr2.ReadLine();
tr2.Close();
}
catch (Exception)
{
throw;
}
...
}
Yes, those 2 approaches have almost the same effect; rethrowing will unwind the stack of the exception - meaning the stack frames "below" the method where the throw; will be discarded. They'll still be in the stack trace, but you won't be able to access their local variables in the debugger unless you break on thrown exceptions.
A catch/throw block like the one below where you don't do anything with the exception (like logging), is useless:
catch (Exception)
{
throw;
}
Remove it to clean up, in both your samples. In general, avoid entering a catch block if possible
And your method has another exception related problem, it does not free resources properly. The tr2.Close(); belongs in a finally clause but it's much easier to let the compiler handle that with a using() {} block :
void MyFileHandlingMethod()
{
...
using (TextReader tr2 = new StreamReader(nfilepath))
{
resultN = tr2.ReadLine();
} //tr2.Dispose() inserted automatically here
...
}
First of all you should use the using block with resources as this will take care of closing your resources correctly. The second example is pretty much useless as you don't do any work in the exception handler. Either you should remove it, or wrap it in another Exception to add some information.
Yes, the result is the same.
However, both will result in an unclosed stream if there is an error while reading it. You should use a using block or a try ... finally to make sure that the stream is closed:
using (TextReader tr2 = new StreamReader(nfilepath)) {
resultN = tr2.ReadLine();
}
Note that there is no Close in this code. The using block will dispose the StreamReader, which will close the stream.
The using block is compiled into a try ... finally which it uses to make sure that the StreamReader is always disposed, but the exception will bubble up to the calling method.
I suggest you use your first example, with these changes:
try
{
MyFileHandlingMethod();
}
catch (IOException ex)
{
string recfilepath = "...";
string rectoadd = "RecDateTime=" + DateTime.Now.ToString()+ ex.Message.ToString();
File.AppendAllText(recfilepath, rectoadd);
throw; // rethrow the same exception.
}
// no need for second catch}
You probably want to rethrow the exception once you have logged it, because you are not doing any actual recovery from the error.
Whatever is inside finally blocks is executed (almost) always, so what's the difference between enclosing code into it or leaving it unclosed?
The code inside a finally block will get executed regardless of whether or not there is an exception. This comes in very handy when it comes to certain housekeeping functions you need to always run like closing connections.
Now, I'm guessing your question is why you should do this:
try
{
doSomething();
}
catch
{
catchSomething();
}
finally
{
alwaysDoThis();
}
When you can do this:
try
{
doSomething();
}
catch
{
catchSomething();
}
alwaysDoThis();
The answer is that a lot of times the code inside your catch statement will either rethrow an exception or break out of the current function. With the latter code, the "alwaysDoThis();" call won't execute if the code inside the catch statement issues a return or throws a new exception.
Most advantages of using try-finally have already been pointed out, but I thought I'd add this one:
try
{
// Code here that might throw an exception...
if (arbitraryCondition)
{
return true;
}
// Code here that might throw an exception...
}
finally
{
// Code here gets executed regardless of whether "return true;" was called within the try block (i.e. regardless of the value of arbitraryCondition).
}
This behaviour makes it very useful in various situations, particularly when you need to perform cleanup (dispose resources), though a using block is often better in this case.
Because finally will get executed even if you do not handle an exception in a catch block.
any time you use unmanaged code requests like stream readers, db requests, etc; and you want to catch the exception then use try catch finally and close the stream, data reader, etc. in the finally, if you don't when it errors the connection doesn't get closed, this is really bad with db requests
SqlConnection myConn = new SqlConnection("Connectionstring");
try
{
myConn.Open();
//make na DB Request
}
catch (Exception DBException)
{
//do somehting with exception
}
finally
{
myConn.Close();
myConn.Dispose();
}
if you don't want to catch the error then use
using (SqlConnection myConn = new SqlConnection("Connectionstring"))
{
myConn.Open();
//make na DB Request
myConn.Close();
}
and the connection object will be disposed of automatically if there is an error, but you don't capture the error
Finally statements can execute even after return.
private int myfun()
{
int a = 100; //any number
int b = 0;
try
{
a = (5 / b);
return a;
}
catch (Exception ex)
{
Response.Write(ex.Message);
return a;
}
// Response.Write("Statement after return before finally"); -->this will give error "Syntax error, 'try' expected"
finally
{
Response.Write("Statement after return in finally"); // --> This will execute , even after having return code above
}
Response.Write("Statement after return after finally"); // -->Unreachable code
}
finally, as in:
try {
// do something risky
} catch (Exception ex) {
// handle an exception
} finally {
// do any required cleanup
}
is a guaranteed opportunity to execute code after your try..catch block, regardless of whether or not your try block threw an exception.
That makes it perfect for things like releasing resources, db connections, file handles, etc.
i will explain the use of finally with a file reader exception Example
with out using finally
try{
StreamReader strReader = new StreamReader(#"C:\Ariven\Project\Data.txt");
Console.WriteLine(strReader.ReadeToEnd());
StreamReader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
in the above example if the file called Data.txt is missing, an exception will be thrown and will be handled but the statement called StreamReader.Close(); will never be executed.
Because of this resources associated with reader was never released.
To solve the above issue, we use finally
StreamReader strReader = null;
try{
strReader = new StreamReader(#"C:\Ariven\Project\Data.txt");
Console.WriteLine(strReader.ReadeToEnd());
}
catch (Exception ex){
Console.WriteLine(ex.Message);
}
finally{
if (strReader != null){
StreamReader.Close();
}
}
Happy Coding :)
Note:
"#" is used to create a verbatim string, to avoid error of "Unrecognized escape sequence".
The # symbol means to read that string literally, and don't interpret control characters otherwise.
Say you need to set the cursor back to the default pointer instead of a waiting (hourglass) cursor. If an exception is thrown before setting the cursor, and doesn't outright crash the app, you could be left with a confusing cursor.
Sometimes you don't want to handle an exception (no catch block), but you want some cleanup code to execute.
For example:
try
{
// exception (or not)
}
finally
{
// clean up always
}
The finally block is valuable for cleaning up any resources allocated in the try block as well as running any code that must execute even if there is an exception. Control is always passed to the finally block regardless of how the try block exits.
Ahh...I think I see what you're saying! Took me a sec...you're wondering "why place it in the finally block instead of after the finally block and completely outside the try-catch-finally".
As an example, it might be because you are halting execution if you throw an error, but you still want to clean up resources, such as open files, database connections, etc.
Control Flow of the Finally Block is either after the Try or Catch block.
[1. First Code]
[2. Try]
[3. Catch]
[4. Finally]
[5. After Code]
with Exception
1 > 2 > 3 > 4 > 5
if 3 has a Return statement
1 > 2 > 3 > 4
without Exception
1 > 2 > 4 > 5
if 2 has a return statement
1 > 2 > 4
As mentioned in the documentation:
A common usage of catch and finally together is to obtain and use resources in a try block, deal with exceptional circumstances in a catch block, and release the resources in the finally block.
It is also worth reading this, which states:
Once a matching catch clause is found, the system prepares to transfer control to the first statement of the catch clause. Before execution of the catch clause begins, the system first executes, in order, any finally clauses that were associated with try statements more nested that than the one that caught the exception.
So it is clear that code which resides in a finally clause will be executed even if a prior catch clause had a return statement.