C# can't avoid nested try-catch - c#

I am pretty new to C#.
I am currently writing a WebSocket application, and I need to handle the NullReferenceException when the client disconnects, as I am constantly reading data from ClientSocket.
So the trouble is:
When I place the second try-catch block inside the first one, I am able to catch the NullReferenceException.
But when I remove the nested try-catch and try to catch the mentioned exception, it goes straight to the "finally" block.
try
{
using StreamReader streamReader = new StreamReader(stream);
while (true)
{
try
{
command = streamReader.ReadLine().Trim();
}
catch (NullReferenceException)
{
blah-blah
break;
}
}
}
//I place the NullReferenceException when removing the nested try-catch
catch (Exception e)
{
blah-blah
}
finally
{
blah-blah
}

You'll need to check exception type on the outer catch or simply throw NullReferenceException again from the first catch.

using (StreamReader streamReader = new StreamReader(stream))
{
while (true)
{
try
{
command = streamReader.ReadLine().Trim();
}
catch (NullReferenceException)
{
blah-blah
break;
}
}
}
more like your streamReader is null.

Related

C# - Try/Catch/Finally and Using proper order

I know this question has been asked quite a few times but i still don't understand what the proper order should be.
If you want to catch an exception in the objects creation you have to put the try and catch outside of the using statement:
try { using... } catch (Exception e) { }
And if you want to catch an exception after the objects creation then:
using(...) { try {...} catch (Exception e) {} }
But what if you want to catch both during and after the objects creation? Would it be:
try { using(...) { try {...} catch (Exception e) {} } } catch (Exception e) { }
Or would it be better to just use a try, catch, and a finally with a dispose?
The using block is more about the Disposal than the creation. As mentioned in the documentation, it's a shortcut to this code:
{
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
}
This is the definition of a try-catch block
The try block contains the guarded code that may cause the exception.
The block is executed until an exception is thrown or it is completed
successfully.
So from there, the strategy is up to you. This piece of code:
try
{
using(Font font1 = new Font("Arial", 10.0f))
{
byte charset = font1.GdiCharSet;
}
}
will be translated as:
try
{
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
}
As you can see, you are catching exceptions cause by the constructor, the block and also the Dispose.
Whereas this:
using(Font font1 = new Font("Arial", 10.0f))
{
try
{
byte charset = font1.GdiCharSet;
}
}
will be translated as:
Font font1 = new Font("Arial", 10.0f);
try
{
try //This is your try
{
byte charset = font1.GdiCharSet;
}
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
So here you will catch exception cause neither by the constructor nor the Dispose.
Any exception thrown within the context of your try block will be handled by the corresponding catch block. You can have, in this instance, one try block that can catch exceptions from multiple sources and handle them as you wish. Consider the following code...
try
{
using(var con = DataService.GetSomethingDisposable()) // Possible InvalidOperationException();
{
// Do what you need here
// Possible Exception here
}
}
catch(InvalidOperationException ex)
{
// Handle as you will
}
catch(Exception ex) // Catch any other exception
{
// Handle as you will
}
So with this you can catch and respond to any exception that arises with the same try...catch block.
MSDN Reference https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement
When the lifetime of an IDisposable object is limited to a single
method, you should declare and instantiate it in the using statement.
The using statement calls the Dispose method on the object in the
correct way, and (when you use it as shown earlier) it also causes the
object itself to go out of scope as soon as Dispose is called. Within
the using block, the object is read-only and cannot be modified or
reassigned.
Option 1 would catch both scenarios:
try { using() } catch (Exception) {}
If you create a new object which throws an exception on initialisation, the exception will be caught in your catch block.
Equally, if something inside your using block throws an exception, that will also be caught in the catch block.
An exception will always bubble up to the first catch block which is capturing that type of exception. If there's nothing to catch the exception, it'll likely bubble all the way up and terminate your application

Why does Resharper think that this catch clause is redundant? [duplicate]

This question already has answers here:
Why does resharper say 'Catch clause with single 'throw' statement is redundant'?
(6 answers)
Closed 6 years ago.
Resharper thinks the last catch clause is redundant. Why?
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(requestUrl);
try
{
var response = (HttpWebResponse) request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
var jsonResult = streamReader.ReadToEnd();
}
}
catch (WebException e)
{
Exception newEx;
if (e.Response != null)
{
using (var sr = new StreamReader(e.Response.GetResponseStream()))
{
newEx = new Exception(sr.ReadToEnd(), e);
}
}
else
{
newEx = new Exception(e.Message, e);
}
throw newEx;
}
catch (Exception ex) // Resharper thinks this clause is redundant
{
throw;
}
Because it is a default behavior - not caught exceptions will go further without need to rethrow them.
C# reference:
When an exception is thrown, the common language runtime (CLR) looks for the catch statement that handles this exception. If the currently executing method does not contain such a catch block, the CLR looks at the method that called the current method, and so on up the call stack.
In your particular case if you will not rethrow exceptions, other then WebException clr will continue to unwind stack looking for next try-catch.
If you rethrow that exceptions, clr will continue to unwind stack looking for next try-catch too.
So, no difference.
Probably because your catch block isn't doing anything except rethrowing the same exception:
catch (Exception ex) // Resharper thinks this clause is redundant
{
throw;
}
You could proof it by adding some code in that catch block.

C# newbie - if inside if which is inside another if and so on & try-catch inside try-catch which is inside another try-catch

Would you excuse a newbie to C# # Windows Phone development, I'm starting this because I want to write a weather app for my Windows Phone, hope that wouldn't be a stupid reason.
Also apologize for my poor English.
Mostly speaking, my code is copy & paste from the internet, I also find a lot of help from Stackoverflow, I own you a thanks!
So far, my code runs just fine, I just have some newbie questions regarding the code structure or coding behavior, or something else.
You can see the part of my code as following (you can ignore the detail, but only care about the if and try-catch blocks):
StreamReader LastReader = null;
if (IsolatedStorageSettings.ApplicationSettings.Contains("UpdateAllDay"))
{
try
{
if (IsolatedStorageSettings.ApplicationSettings["UpdateAllDay"].ToString() == "false")
{
try
{
if (IsolatedStorageSettings.ApplicationSettings.Contains("UpdateStartTime") && IsolatedStorageSettings.ApplicationSettings.Contains("UpdateEndTime"))
{
try
{
if (DateTime.Now > Convert.ToDateTime(IsolatedStorageSettings.ApplicationSettings["UpdateStartTime"].ToString()) && DateTime.Now < Convert.ToDateTime(IsolatedStorageSettings.ApplicationSettings["UpdateEndTime"].ToString()))
{
IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication();
if (IsolatedStorageSettings.ApplicationSettings.Contains("UpdateRate") && isoFile.FileExists("LastUpdateTime.txt"))
{
try
{
LastReader = new StreamReader(new IsolatedStorageFileStream("LastUpdateTime.txt", FileMode.Open, isoFile));
if ((DateTime.Now - Convert.ToDateTime(LastReader.ReadLine())).TotalSeconds >Convert.ToInt32(IsolatedStorageSettings.ApplicationSettings["UpdateRate"].ToString()))
{
LastReader.Close();
if (IsolatedStorageSettings.ApplicationSettings.Contains("CityID"))
{
HttpClient client = new HttpClient();
string url = "http://m.weather.com.cn/data/{0}.html";
string baseUrl = string.Format(url, IsolatedStorageSettings.ApplicationSettings["CityID"].ToString());
try
{
string WeatherResult = await client.GetStringAsync(baseUrl);
if (WeatherResult != null)
{
StreamWriter Writer = new StreamWriter(new IsolatedStorageFileStream("WeatherResult.txt", FileMode.OpenOrCreate, isoFile));
Writer.WriteLine(WeatherResult);
Writer.Close();
RootWeatherCore apiData = JsonConvert.DeserializeObject<RootWeatherCore>(WeatherResult);
await GetData(apiData);
StreamWriter LastUpdateTime_Writer = new StreamWriter(new IsolatedStorageFileStream("LastUpdateTime.txt", FileMode.OpenOrCreate, isoFile));
LastUpdateTime_Writer.WriteLine(DateTime.Now);
LastUpdateTime_Writer.Close();
return "true";
}
}
catch (Exception) { return "1"; }
}
}
}
catch (Exception) { return "1"; }
}
}
return "1";
}
catch (Exception) { return "1"; }
}
}
catch (Exception) { return "1"; }
}
else
{
IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication();
if (IsolatedStorageSettings.ApplicationSettings.Contains("UpdateRate") && isoFile.FileExists("LastUpdateTime.txt"))
{
try
{
LastReader = new StreamReader(new IsolatedStorageFileStream("LastUpdateTime.txt", FileMode.Open, isoFile));
if ((DateTime.Now - Convert.ToDateTime(LastReader.ReadLine())).TotalSeconds > Convert.ToInt32(IsolatedStorageSettings.ApplicationSettings["UpdateRate"].ToString()))
{
LastReader.Close();
if (IsolatedStorageSettings.ApplicationSettings.Contains("CityID"))
{
HttpClient client = new HttpClient();
string url = "http://m.weather.com.cn/data/{0}.html";
string baseUrl = string.Format(url, IsolatedStorageSettings.ApplicationSettings["CityID"].ToString());
try
{
string WeatherResult = await client.GetStringAsync(baseUrl);
if (WeatherResult != null)
{
StreamWriter Writer = new StreamWriter(new IsolatedStorageFileStream("WeatherResult.txt", FileMode.OpenOrCreate, isoFile));
Writer.WriteLine(WeatherResult);
Writer.Close();
RootWeatherCore apiData = JsonConvert.DeserializeObject<RootWeatherCore>(WeatherResult);
await GetData(apiData);
StreamWriter LastUpdateTime_Writer = new StreamWriter(new IsolatedStorageFileStream("LastUpdateTime.txt", FileMode.OpenOrCreate, isoFile));
LastUpdateTime_Writer.WriteLine(DateTime.Now);
LastUpdateTime_Writer.Close();
return "true";
}
}
catch (Exception) { return "1"; }
}
}
}
catch (Exception) { return "1"; }
}
return "1";
}
}
catch (Exception) { return "1"; }
}
Would it scare you? Actually I was scared when I wrote this out. It looks kind of urgly or poorly structured, isn't it?
So, my question is, is it a good practice or behavior to use too much loop of if block inside another if block, and try-catch block inside another try-catch block?
I have so many if block because I think the app would function differently under different conditions.
And I use try-catch a lot because I need to handle with the Isolated Storage in Windows Phone environment, which is suggested by many guru from Stackoverflow and also other website.
Is this a normal coding structure or behavior? Then I should get used to it.
Or is there a better method that I am not aware of?
Or would it be a good idea to use a single & "big" try-catch to put all the code inside it? (If I don't care what's the exact exceptions)
Any suggestions or comments would be appreciated, thanks!
That structure definitely looks overly complex. The only reason that I could think that you would have so many nested try...catch blocks is that you think certain operations may fail for a particular reason.
The problem with doing the handling that way is that comes in on how and when you want to handle the exception in one of the nested catches.
If this is the case you can have multiple catch statements for a single try.
Something like this:
try
{
//Do Something
}
catch(<ExceptionType1> e1) {}
catch(<ExcetionType2> e2){}
catch(Exception e){}
Or if you do not care about the exception you can simply have a general catch that catches all
try
{
//Do Something
}
catch {}
for starters, having try blocks inside each other doesn't do anything as they don't catch different exceptions.
also your catch blocks returns 1. and functions end when they hit a return function. so all ur try/catch is equivalent to a big catch block.
In general its a good idea to avoid so many nested if's. I'm not familiar with windows phone programming, but a good object oriented solution is to write a function like this
boolean isCorrectCondition(ApplicationSetting as)
{
return condition1 && condition2 && ... && last condition;
}
and instead of ur monstrous nest of if statements have something like
if(isCorrectCondition(as)) {
// do something here
}

How to efficiently manage a Stream with try / catch / finally C#

I recently discussed with a coworker who told me that I was managing incorrently a stream into a try / catch / block. So I wanna know what would be a good approach for you.
try
{
StreamReader sr = new StreamReader("TestFile.txt");
//After that, here an operation of about 30 seconds to fulfill;
}
catch (IOException ioex)
{
throw new IOException("An error occurred while processing the file.", ioex);
}
catch (Exception ex)
{
throw new Exception("An generic error ocurred.");
}
finally
{
if(sr != null){
stream.Close();
stream = null;
}
}
He stated that having 2 Exception are unnecessary, even using the IOException. We can use only Exception. But the only thing that I want is to recognize where exactly the exception has been produced, because after opening the file, an operation of about 30 seconds will be performed.
So what would you think? We saw this MS example (http://msdn.microsoft.com/fr-Fr/library/system.io.streamreader.aspx) which it's simplier but in terms of performance or clean code, you find something strange?
Your opinions please!
-EDIT-----------------
Ok, I see the point but we were discussing about the Catch IOException and just using the Exception. In my opinion, like as in the example above you can know where the error ocurred; at the moment of managing the file or in the process after opening the file. That's my first question. And now, what do you think about this change below.
try
{
using(StreamReader sr = new StreamReader("TestFile.txt"))
{
//After that, here an operation of about 30 seconds to fulfill;
}
}
catch (Exception ex)
{
throw new Exception("An generic error ocurred.");
}
finally
{
if(sr != null){
stream.Close();
stream = null;
}
}
-------------------EDIT 2------------------------
Finally, I hope this would be my final solution. Thank you so much for your answers. So using is faster, efficient and just one exception is necessary.
try
{
using (StreamReader stream = sr = new StreamReader("TestFile.txt"))
{
//Operation
}
}
catch (Exception e)
{
throw new Exception(String.Format("An error ocurred while executing the data import: {0}", e.Message), e);
}
Any other comment would be appreciated!
you can use using block as below, and it will dispose the stream even on exception occurred
using (StreamReader sr = new StreamReader("TestFile.txt"))
{
// do something with sr
}
Catch Exception if you're going to do something about. If you can't fix the problem, there's no point in catching it.
if you can't resolve the exception, it's best to just let the exception bubble up the exception and catch it there.
try
{
using(StreamReader sr = new StreamReader("TestFile.txt"))
{
// your code
}
}
catch (IOException ioex)
{
// do something to fix the problem
// log the exception
}
Don't catch an exception only to throw the same exception immediately, only now with less information and missing the stack frame of where the exception actually occurred.
If I came across something like
catch (Exception ex)
{
throw new Exception("An generic error ocurred.");
}
in a code review I would fail that review (not just for the grammar and spelling mistake either ;-)
At the very least, you should throw it with the original exception as an inner exception.
catch (Exception ex)
{
throw new Exception("A generic error occurred.", ex)
}
But to be perfectly frank, in this sample code it adds nothing whatsoever, it would be better removed entirely imo.
If you're rethrowing the exception instead of catching it, why bother creating a new exception? You're throwing away valuable information. There's literally no point in catching an exception only to throw it again. Nor is there any point replacing a helpful exception (as in, it's got all the diagnostic information anyone upstream might need) and replacing it with a generic exception.
For your situation, I'd simply:
using(var sr=new StreamReader())
{
//some code
}
all your other improvements are quite the opposite.

try/catch + using, right syntax

Which one:
using (var myObject = new MyClass())
{
try
{
// something here...
}
catch(Exception ex)
{
// Handle exception
}
}
OR
try
{
using (var myObject = new MyClass())
{
// something here...
}
}
catch(Exception ex)
{
// Handle exception
}
I prefer the second one. May as well trap errors relating to the creation of the object as well.
Since a using block is just a syntax simplification of a try/finally (MSDN), personally I'd go with the following, though I doubt it's significantly different than your second option:
MyClass myObject = null;
try
{
myObject = new MyClass();
//important stuff
}
catch (Exception ex)
{
//handle exception
}
finally
{
if (myObject is IDisposable)
{
myObject.Dispose();
}
}
It depends. If you are using Windows Communication Foundation (WCF), using(...) { try... } will not work correctly if the proxy in using statement is in exception state, i.e. Disposing this proxy will cause another exception.
Personally, I believe in minimal handling approach, i.e. handle only exception you are aware of at the point of execution. In other word, if you know that the initialization of a variable in using may throw a particular exception, I wrap it with try-catch. Similarly, if within using body something may happen, which is not directly related to the variable in using, then I wrap it with another try for that particular exception. I rarely use Exception in my catches.
But I do like IDisposable and using though so I maybe biased.
If your catch statement needs to access the variable declared in a using statement, then inside is your only option.
If your catch statement needs the object referenced in the using before it is disposed, then inside is your only option.
If your catch statement takes an action of unknown duration, like displaying a message to the user, and you would like to dispose of your resources before that happens, then outside is your best option.
Whenever I have a scenerio similar to this, the try-catch block is usually in a different method further up the call stack from the using. It is not typical for a method to know how to handle exceptions that occur within it like this.
So my general recomendation is outside—way outside.
private void saveButton_Click(object sender, EventArgs args)
{
try
{
SaveFile(myFile); // The using statement will appear somewhere in here.
}
catch (IOException ex)
{
MessageBox.Show(ex.Message);
}
}
Both are valid syntax. It really comes down to what you want to do: if you want to catch errors relating to creating/disposing the object, use the second. If not, use the first.
There is one important thing which I'll call out here: The first one will not catch any exception arising out of calling the MyClass constructor.
From C# 8.0 on, you can simplify using statements under some conditions to get rid of the nested block, and then it just applies to the enclosing block.
So your two examples can be reduced to:
using var myObject = new MyClass();
try
{
// something here...
}
catch(Exception ex)
{
// Handle exception
}
And:
try
{
using var myObject = new MyClass();
// something here...
}
catch(Exception ex)
{
// Handle exception
}
Both of which are pretty clear; and then that reduces the choice between the two to a matter of what you want the scope of the object to be, where you want to handle instantiation errors, and when you want to dispose of it.
If the object you are initializing in the Using() block might throw any exception then you should go for the second syntax otherwise both the equally valid.
In my scenario, I had to open a file and I was passing filePath in the constructor of the object which I was initializing in the Using() block and it might throw exception if the filePath is wrong/empty. So in this case, second syntax makes sense.
My sample code :-
try
{
using (var obj= new MyClass("fileName.extension"))
{
}
}
catch(Exception ex)
{
//Take actions according to the exception.
}
From C# 8.0, I prefer to use the second one same like this
public class Person : IDisposable
{
public Person()
{
int a = 0;
int b = Id / a;
}
public int Id { get; set; }
public void Dispose()
{
}
}
and then
static void Main(string[] args)
{
try
{
using var person = new Person();
}
catch (Exception ex) when
(ex.TargetSite.DeclaringType.Name == nameof(Person) &&
ex.TargetSite.MemberType == System.Reflection.MemberTypes.Constructor)
{
Debug.Write("Error Constructor Person");
}
catch (Exception ex) when
(ex.TargetSite.DeclaringType.Name == nameof(Person) &&
ex.TargetSite.MemberType != System.Reflection.MemberTypes.Constructor)
{
Debug.Write("Error Person");
}
catch (Exception ex)
{
Debug.Write(ex.Message);
}
finally
{
Debug.Write("finally");
}
}

Categories

Resources