Exception handling.

Started by
27 comments, last by ANSI2000 21 years, 11 months ago
I have the following class...

class WinsockManager
{
public:

	static WinsockManager* getInstance()
	{
		if(instance == NULL)
			instance = new WinsockManager();
		
		return(instance);		
	}
	
	void startUp(WORD pVersion) throw(WinsockException)
	{
		int errorCode = 0;
		
		if(WSAStartup(pVersion, &WSAData) != 0)
		{  
			errorCode = WSAGetLastError();
			
			throw WinsockException("WSAStratup() failed.", errorCode);
		}

		// Make sure that Winsock is the requested version.
		if(WSAData.wVersion != pVersion)
		{
			cleanUp();

			throw WinsockException("Incompatible winsock version.", 0);
		}	
	}
	
	void cleanUp() throw(WinsockException)
	{
		int errorCode = 0;
		
		if(WSACleanup() == SOCKET_ERROR)
		{
			errorCode = WSAGetLastError();

			throw WinsockException("WSACleanup() failed.", errorCode);
		}
	}

protected:

	WinsockManager() {};

private:

	WSADATA WSAData;
    
	static WinsockManager *instance;
};
  
Because cleanUp() throws an exception do I have to catch the exception within startUp() or the exception will climb up the ladder and the try catch block of startUp() will catch the cleanUp() exception? [edited by - ANSI2000 on April 29, 2002 10:54:59 AM]
Advertisement
Cleanup code should *never* throw, just like dtors.
So sujestion would be...
RAII (Resource aqusition is initialization). Hunt google.

Your class is also very weird that it looks like a singleton, but yet you have startup/shutdown methods.

I use a simple static instance to call the WSAStartUp & WSACleanUp. No need to make them throw or anything, if WSAStartp fails, so will your first call to create a socket, you can gracefully detect the error then. You could make the WSAInit singleton assert on failure, but I wouldn''t have it throw.

Throwing in ctor''s is deep magic - throwing in dtor''s is black magic. Don''t do either. xps not with MSVC - you can''t always write a throwing ctor in MSVC correctly, and you can''t ever write an air-tight throwing dtor. There''s at least one item in www.gotw.com devoted to this topic (throwing ctor''s).

Use a factory instead, and have it automagically call the intialization code for the objects. It can fail gracefully then (i.e. clean-up properly), beit an exception, error code, or null return.

The manager could call WSAStartUp in it''s ctor and WSACleanUp in it''s dtor, but don''t throw if they fail - Press On Regardless.
Let the Create<TCPSocket> method fail.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
What is wrong with throwing within Ctors? If you follow RAII closely, then throwing within ctor are fine.

In this specific example, we require a class that does this

  class WSAResource{public:   WSAResource()   {      if ( ! WSAStartup(..) )          throw;   }   ~WSAResource()   {      WSACleanup();   }};  


The winsock manager singleton declares a static stack instance of this


WSAResource wsaresource_;


So the ctor of WSAResource completes, you would have initialized winsock. If any exception occurs, the dtor would call WSACleanup.
ctors always complete. That''s why you shouldn''t throw within them.

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ ]
[ MS RTFM [MSDN] | SGI STL Docs | Boost ]
[ Google! | Asking Smart Questions | Jargon File ]
Thanks to Kylotan for the idea!
Well my class is a singleton... And I need it to be that way...

As for detecting errors I need to know if Winsock has initilaized correctly if so I do not execute the rest of the application and just quit right away. My application is a "high" performance banking "broker"... The app acts as "router" it listens on one socket receiving transactions queing them and finally sending them to the financial institution. The bank finally responds, teh application matches the transaction within the queue and sends back the response to the client that connected to the listening socket. Winsock is the most important factor of the app. In my WinsockManager singleton, I always checked to see the if Winsock initialized properly, but not if it didn''t. But I have ran into this problem...

The connection to the bank must be persistant as in always connected... Now teh case is because am in development... I shut down my app often making changes... The problem arises that sometimes when I restart my application, either the application will connect but no data will go throuogh to the bank when Isend it, or the application will not reconnect period.... The connection to the bank is through a VPN.

So I thought let me catch the WSACleanup errors to see if Winsock is freeing all resources... So I guess the simplest would be just to print out the error... Instead of catching an exception...

Which this brings me to my other post have you guys had a chance to look at that one?
Do you mean dtors should always complete?

Ctors can throw, and it is a legitimate (only?) way to signal a constructor failure.

Without throwing an exception in ctor, you have no way to signal a ctor failure. The other solution is to have a method to test if the object is valid before use. (That is klunky)

At the most unlikely case, what happens if you want to create an object but there is not enough memory? You throw an OutOfMemory exception of course.
quote:Original post by ANSI2000
So I thought let me catch the WSACleanup errors to see if Winsock is freeing all resources... So I guess the simplest would be just to print out the error... Instead of catching an exception...

Which this brings me to my other post have you guys had a chance to look at that one?


If you make use WSACreate is called successfully (using the RAII class), WSACleanup will not failed. The only time when WSACleanup would fail is because you never called WSACreate(). Have faith with these C APIs.

If data failed to send through the winsock singleton, it is consider quite a common activity. Throw only an exception if you want the whole application to quit. An error code would be more appropriate to indicate the data is sent successfully or not.

I''m no winsock expert but I thought you need to rephrase your question. I suspect most people don''t understand what you are asking.

This topic is closed to new replies.

Advertisement