Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it good practice to put try-catch in a loop until all statements in the try block is executed without any exceptions?

I was trying to develop a multicast receiver program and socket initialization was done as shown below:

    public void initializeThread()
    {
        statuscheckthread = new Thread(SetSocketOptions);
        statuscheckthread.IsBackground = true;
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        rxsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        iep = new IPEndPoint(IPAddress.Any, 9191);
        rxsock.Bind(iep);
        ep = (EndPoint)iep;

        initializeThread();
        statuscheckthread.Start();
    }

    public void SetSocketOptions()
    {
         initializeThread(); //re-initializes thread thus making it not alive
         while (true)
         {
             if (NetworkInterface.GetIsNetworkAvailable())
             {
                 bool sockOptnSet = false;
                 while (!sockOptnSet)
                 {
                     try
                     {
                         rxsock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("224.50.50.50")));
                         rxsock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 64);
                         sockOptnSet = true;
                     }
                     catch
                     {
                         //Catch exception here
                     }
                 }
             }
             break; // Break out from loop once socket options are set
         }
     }

When my PC is not connected to a network, SetSocketOption method was throwing exception and even after network is connected, I was unable to receive data because socket options are not set.

To avoid this I used a thread which runs in the background checking for network availability and once network is available, it sets the socket options.

It works properly in some PC's but in some others, NetworkInterface.GetIsNetworkAvailable() returned true before network got connected (while network was being identified) .

So, to make sure Socket options are set, I used a bool variable sockOptnSet which is set as true if all the statements in the try block is executed as shown inside the method public void SetSocketOptions() This program works fine in all PC's I tried, but I am doubtful about how much I can rely on this to work.

My questions are:

1) Is this good practice?

2) If not, what are the possible errors or problems it may cause? And how can I implement it in a better way?

like image 346
Anusri N C Avatar asked Jan 14 '14 08:01

Anusri N C


1 Answers

Is this a good practice?

No, not a good practice. The vast majority of exceptions, including your first one, fall in the category of vexing exceptions. Software is supposed to work, worked well when you tested it, but doesn't on the user's machine. Something went wrong but you do not know what and there isn't anything meaningful that you can do about it. Trying to keep your program going is not useful, it cannot do the job it is supposed to do. In your case, there's no hope that the socket is ever going to receive data when there is no network. And, as you found out, trying to work around the problem just begets more problems. That's normal.

If this is bad practice, how can I implement it in a better way?

You need help from a human. The user is going to have to setup the machine to provide a working network connection. This requires a user interface, you must have a way to tell a human what he needs to do to solve your problem. You can make that as intricate or as simple as you desire. Just an error message, a verbatim copy of the Exception.Message can be enough. Writing an event handler for the AppDomain.CurrentDomain.UnhandledException event is a very good (and required) strategy. Microsoft spent an enormous amount of effort to make exception messages as clear and helpful as possible, even localizing them for you in the user's native language, you want to take advantage of that. Even if the exception message is mystifying, a quick Google query on the message text returns hundreds of hits. With this event handler in place, you don't have to do anything special. Your program automatically terminates and your user knows what to do about it.

You can certainly make it more intricate, you discovered that SetSocketOption() is liable to fail right after the network becomes available but works when you wait long enough. So this is actually an error condition that you can work around, just by waiting long enough. Whether you should write the code to handle this is something that you have to decide for yourself. It is something you write when you have enough experience with the way your program behaves, you never write it up front. Usually as a result from feedback from the users of your program.

like image 135
Hans Passant Avatar answered Oct 25 '22 08:10

Hans Passant