When writing an application which uses the Winsock library, error checking and handling is a must, because of the unreliable nature of Winsock (you can't guarantee that a machine is always connected to the network, for example).  Some error situations are recoverable, and some are not.  According to this fact, you must choose to report the occurred error to the user, write a system Event Log entry, append information to a log file, or discard the error.  You can report the error code, but probably a message box stating that “Error 10015” occurred will not mean much to the user.  You need some method to convert the error message to a human readable string, and then use that string when reporting, either with or without the error code number.

You would expect to be able to call FormatMessage( ) passing the error code returned from WSAGetLastError( ) to retrieve a textual representation of the error message.  Unfortunately, life is not always that easy.  Some implementations of Winsock provide this facility, while some do not.  In other words, you can't rely on FormatMessage( ) returning anything useful when it comes to a Winsock error.

The easiest solution for this case is to write your own DLL which does the translation job for you.  If you don't want to reinvent the wheel, you can use the NetErr.dll written by me.  You can download the source code with a test application as well as a pre-built and ready to use version of the DLL plus its corresponding NetErr.lib file.

The DLL is simple enough.  It exports some C-style functions, and stores the text for the error messages as a string table resource.  Each entry in the string table has an ID equal to the error code.  The DLL supports both Unicode and ANSI, and the NetErr.h header file defines some generic macros that are mapped to the correct version of each function in the usual way the Windows header files are organized.  To use the DLL, you simply include neterr_lib.h and link with NetErr.lib.  You should also make sure that at run time, the DLL can be found, and loaded by your application.  Because the usage of the string table resource, you can easily replace it with another string table resource containing the translated version of the texts if you plan for internationalization of your application.

Here I am going to describe each of the exported functions.  They are easy to call, only you should get familiar with the syntax:

  • BOOL __stdcall neterrIsDescriptionAvailable( int nErrorCode );

Checks to see if the DLL can translate a specific error code number.
nErrorCode is the error code number to be checked.  The function returns TRUE if the error can be translated, and FALSE otherwise.

  • int __stdcall neterrGetLastError( VOID );

Returns the last Winsock error code number.

  • VOID __stdcall neterrSetLastError( int nErrorCode );

Sets the last Winsock error code number.
nErrorCode is the error code number to be set.

  • BOOL __stdcall neterrGetDescriptionComplete( int nErrorCode, LPTSTR pszDescription, DWORD cchDescription );

Returns the complete error description text for a particular error code number.
nErrorCode specifies the error code number.  pszDescription is a pointer to the memory buffer to be filled with the error code description.  This buffer should contain at least 1024 characters.  cchDescription is the length of the buffer, in characters.  This function returns TRUE if it's successful, and FALSE otherwise.

The error text translation returned by this function contains both a title, and descriptive error description.

  • BOOL __stdcall neterrGetDescriptionTitle( int nErrorCode, LPTSTR pszTitle, DWORD cchTitle );

Returns a short error description text for a particular error code number.
nErrorCode specifies the error code number.  pszTitle is a pointer to the memory buffer to be filled with the error code description.  This buffer should contain at least 1024 characters.  cchTitle is the length of the buffer, in characters.  This function returns TRUE if it's successful, and FALSE otherwise.

The error text translation returned by this function is a short message indicating the error, and is useful for small user interfaces.

  • BOOL __stdcall neterrGetDescriptionShort( int nErrorCode, LPTSTR pszShort, DWORD cchShort );

Returns a descriptive error description text for a particular error code number.
nErrorCode specifies the error code number.  pszShort is a pointer to the memory buffer to be filled with the error code description.  This buffer should contain at least 1024 characters.  cchShort is the length of the buffer, in characters.  This function returns TRUE if it's successful, and FALSE otherwise.

The error text translation returned by this function is a descriptive message indicating the error, and is useful for normal user interfaces.

A short point to be noted if you plan to change the string table resource strings.  The strings are in the following format: “TITLE - DESCRIPTION”, where TITLE is the error title, retrieved by the neterrGetDescriptionTitle( ) function, and DESCRIPTION is a descriptive piece of text explaining the error in detail, which is retrieved by the neterrGetDescriptionShort( ) function.  The neterrGetDescriptionComplete( ) function retrieves the whole string, containing both the title and the description of the error message.

You can also compile and run the test application which retrieves the error description for the WSAEWOULDBLOCK Winsock error code.

 Download source code for this article

This article originally appeared on BeginThread.com. It's been republished here, and may contain modifications from the original article.