I have some working code, but the error handling is fairly crude at the moment - it generally sends an error string to standard error and exits. So I would like it to throw an exception and allow the user to deal with it as they choose with a typical handler.
However, having added a try catch block to the code it is giving me a compiler error that I don't understand at all.
My code looks like this:
// -------------------------------------------------------------------------
sockets::TCPSocket::TCPSocket(const char* address, const int port)
{
    this->address    = address;
    this->port       = port;
    this->bufferSize = sockets::TCPSocket::DEF_BUFFER;
    sockets::TCPSocket::init();
}
// -------------------------------------------------------------------------
sockets::TCPSocket::~TCPSocket()
{
    freeaddrinfo(this->addressInfoList);
    close(this->filedes);
}
// -------------------------------------------------------------------------
void sockets::TCPSocket::init()
{
    memset(&(this->addressInfo), 0, sizeof this->addressInfo);
    addressInfo.ai_family   = AF_UNSPEC;      // Either IPv4 or IPv6
    addressInfo.ai_socktype = SOCK_STREAM;    // Uses TCP
    addressInfo.ai_flags    = AI_PASSIVE;     // Accept any IP
    // get the address info
    int status = getaddrinfo(
        this->address,
        std::to_string(this->port).c_str(),
        &(this->addressInfo),
        &(this->addressInfoList)
    );
    if (status != 0)  // any error- segfault if addressInfoList not allocated
    {
        throw GetAddrinfoException();
    }
    // create socket
    this->filedes = socket(
        this->addressInfoList->ai_family,
        this->addressInfoList->ai_socktype,
        this->addressInfoList->ai_protocol
    );
    if (this->filedes == -1)
    {
        std::cerr << "Create socket error: " << strerror(errno) << std::endl;
        exit(EXIT_FAILURE);
    }
}
// -------------------------------------------------------------------------
As you see I am calling a (private) init() function from my constructor. And I throw a GetAddrinfoException in my init() function. If I wrap the call to init() in a try catch wihtin the constructor it works fine. But when I call it from my main - expecting the stack to unwind - I get a compiler error.. like this:
int main()
    {
        using namespace std;
        // Test as client
        const char* TEST_ADDR = "www.google.com";
        try
        {
            sockets::TCPSocket socket = sockets::TCPSocket(TEST_ADDR, 80);
        }
        catch (sockets::GetAddrinfoException e) { /* do something */ }
    return 0;
}
The compiler error lists each of the member functions of TCPSocket and gives this message:
TCPSocket/test.cpp: In function ‘int main()’:
TCPSocket/test.cpp:22:12: error: request for member ‘doConnect’ in ‘socket’, which is of non-class type ‘int(int, int, int) throw ()’
     socket.doConnect();
            ^
TCPSocket/test.cpp:23:12: error: request for member ‘doSend’ in ‘socket’, which is of non-class type ‘int(int, int, int) throw ()’
     socket.doSend("GET / HTTP/1.1\r\nHost: www.redway-soft.com\r\n\r\n");
            ^
TCPSocket/test.cpp:24:20: error: request for member ‘doRecv’ in ‘socket’, which is of non-class type ‘int(int, int, int) throw ()’
     cout << socket.doRecv() << endl;
                    ^
TCPSocket/test.cpp:34:12: error: request for member ‘restart’ in ‘socket’, which is of non-class type ‘int(int, int, int) throw ()’
     socket.restart();
            ^
TCPSocket/test.cpp:35:30: error: request for member ‘doListen’ in ‘socket’, which is of non-class type ‘int(int, int, int) throw ()’
     string received = socket.doListen();
                              ^
Despite searching through multiple tutorials and guides I cannot find any reason for this problem. Any help would be much appreciated.
EDIT:
The class definition looks like this:
#ifndef __TCPSOCKET_HPP__
#define __TCPSOCKET_HPP__
#include <cstring>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <string>
#include <vector>
#include <iostream>
#include <cerrno>
#include <exception>
namespace sockets
{
    class GetAddrinfoException: std::exception
    {
        public:
            virtual const char* what() const throw()
            {
                return "getAddressinfo() failure";
            }
    };
    /**
    * @class TCPSocket, creates a HTTP/TCP Socket. TCPSocket is designed with the idea
    * that it should usually be instantiated in its own thread for most use cases.
    * @param const char* address, e.g. www.google.com
    * @param int port, which port defaults 80
    */
    class TCPSocket
    {
        private:
            /**
            * Instance vars
            */
            struct addrinfo  addressInfo;
            struct addrinfo* addressInfoList;
            int              filedes;
            const char*      address;
            int              port;
            int              bufferSize;
            /**
            * @function init, allows socket to be re-assigned a new address and port
            */
            void init();
        public:
            /**
            * pulbic class vars
            */
            static const int DEF_BUFFER   = 2000;
            static const int DEF_PORT     = 5556;
            static const int DEF_TIMEOUT  = 200000;
            static const int DEF_NUMTRIES = 5;
            /**
            * @constructor
            * @param address, to connect to default is NULL siffnifying server socket
            * @param port, port to connect/listen on
            */
            TCPSocket(const char* address = NULL, const int port = DEF_PORT);
            /**
            * @destructor
            */
            ~TCPSocket();
            /**
            * public getters
            */
            inline const char*            getAddress()         {return this->address;}
            inline const int&             getPort()            {return this->port;}
            inline const struct addrinfo& getAddressInfo()     {return this->addressInfo;}
            inline const int&             getFiledes()         {return this->filedes;}
            inline const struct addrinfo* getAddressInfoList() {return this->addressInfoList;}
            /**
            * @function setBuffer, set bufferSize to custom size
            * @param buffer, the size to set the read in buffer
            */
            inline void setBuffer(int buffer) {this->bufferSize = buffer;}
            /**
            * @function restart, cleans up and then re-initialises the socket with new params
            * @param address, to connect to
            * @param port, port to connect
            */
            void restart(const char* address = NULL, const int port = DEF_PORT);
            /**
            * @function doConnect, connect to target address
            */
            void doConnect();
            /**
            * @function doSend - sends specific message,
            * @param message e.g. "GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n"
            * would send a simple get request, or a html string could be sent back
            * in the case of send from a server socket which is responding to a
            * request.
            */
            void doSend(const char* message);
            /**
            * @function doRecv, gets return data from server
            * @param timeout, length of time to wait (micros) for data def = 100 000
            * @param numtries, number of attempts at reading data if none recv
            * @return message that has been received
            */
            std::string doRecv(int timeout = DEF_TIMEOUT, int numtries = DEF_NUMTRIES);
            /**
            * @function doListen, listens at given port and accepts a connection
            * note that this function is blocking and so any implementation should
            * probably normally be on its own thread/process, a server class should
            * be in charge of managing individual threads and sockets.
            */
            std::string doListen();
            /**
            * @function doClose, closes the filedescripter.
            */
            void doClose();
    };
}
#endif
 
    