Skip to content
This repository has been archived by the owner on Aug 11, 2020. It is now read-only.

Commit

Permalink
Throw custom exceptions (#52)
Browse files Browse the repository at this point in the history
* init work on exception handling

* use internal except class

* Cover factory failures

* Improv query test

* throw when db not specified

* Use make test

* Provide basic docs
  • Loading branch information
awegrzyn authored Feb 24, 2020
1 parent 95d539e commit 4398f8b
Show file tree
Hide file tree
Showing 14 changed files with 101 additions and 21 deletions.
5 changes: 1 addition & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ script:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then cmake ..;
else cmake .. -DCMAKE_C_COMPILER=/usr/bin/gcc-7 -DCMAKE_CXX_COMPILER=/usr/bin/g++-7 -DCMAKE_BUILD_TYPE=Debug; fi;
- make -j
- influx -database "test" -execute "select * from test"
- ./bin/testHttp
- influx -database "test" -execute "select * from test"
- ./bin/testQuery
- make test
after_success:
- |
if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ if (Boost_FOUND)
test/testPoint.cxx
test/testHttp.cxx
test/testQuery.cxx
test/testFactory.cxx
)

foreach (test ${TEST_SRCS})
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@


InfluxDB C++ client library
- Writing points
- Batch write
- Data exploration
- Supported transports
Expand Down
3 changes: 3 additions & 0 deletions include/InfluxDBFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ class InfluxDBFactory
InfluxDBFactory(const InfluxDBFactory&) = delete;

/// InfluxDB factory
/// Provides InfluxDB instance with given transport
/// \param url URL defining transport details
/// \throw InfluxDBException if unrecognised backend or missing protocol
static std::unique_ptr<InfluxDB> Get(std::string url) noexcept(false);

private:
Expand Down
12 changes: 8 additions & 4 deletions src/HTTP.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
///

#include "HTTP.h"
#include "InfluxDBException.h"
#include <iostream>

namespace influxdb
Expand All @@ -20,11 +21,14 @@ void HTTP::initCurl(const std::string& url)
{
CURLcode globalInitResult = curl_global_init(CURL_GLOBAL_ALL);
if (globalInitResult != CURLE_OK) {
throw std::runtime_error(std::string("cURL init") + curl_easy_strerror(globalInitResult));
throw InfluxDBException("HTTP::initCurl", curl_easy_strerror(globalInitResult));
}

std::string writeUrl = url;
auto position = writeUrl.find("?");
if (position == std::string::npos) {
throw InfluxDBException("HTTP::initCurl", "Database not specified");
}
if (writeUrl.at(position - 1) != '/') {
writeUrl.insert(position, "/write");
} else {
Expand Down Expand Up @@ -71,7 +75,7 @@ std::string HTTP::query(const std::string& query)
curl_easy_setopt(readHandle, CURLOPT_WRITEDATA, &buffer);
response = curl_easy_perform(readHandle);
if (response != CURLE_OK) {
throw std::runtime_error(curl_easy_strerror(response));
throw InfluxDBException("HTTP::query", curl_easy_strerror(response));
}
return buffer;
}
Expand Down Expand Up @@ -106,10 +110,10 @@ void HTTP::send(std::string&& post)
response = curl_easy_perform(writeHandle);
curl_easy_getinfo(writeHandle, CURLINFO_RESPONSE_CODE, &responseCode);
if (response != CURLE_OK) {
throw std::runtime_error(curl_easy_strerror(response));
throw InfluxDBException("HTTP::send", curl_easy_strerror(response));
}
if (responseCode < 200 || responseCode > 206) {
throw std::runtime_error("Response code : " + std::to_string(responseCode));
throw InfluxDBException("HTTP::send", "Response code: " + std::to_string(responseCode));
}
}

Expand Down
7 changes: 6 additions & 1 deletion src/HTTP.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ class HTTP : public Transport
~HTTP();

/// Sends point via HTTP POST
/// \throw InfluxDBException when CURL fails on POSTing or response code != 200
void send(std::string&& post) override;

/// Queries database
/// \throw InfluxDBException when CURL GET fails
std::string query(const std::string& query) override;

/// Enable Basic Auth
Expand All @@ -39,8 +41,11 @@ class HTTP : public Transport
void enableSsl();
private:

/// Initilizes CURL and all common options
/// Initilizes CURL for writting and common options
/// \throw InfluxDBException if database (?db=) not specified
void initCurl(const std::string& url);

/// Initializes CURL for reading
void initCurlRead(const std::string& url);

/// CURL pointer configured for writting points
Expand Down
3 changes: 2 additions & 1 deletion src/InfluxDB.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
///

#include "InfluxDB.h"
#include "InfluxDBException.h"

#include <iostream>
#include <memory>
Expand Down Expand Up @@ -119,7 +120,7 @@ std::vector<Point> InfluxDB::query(const std::string& query)
#else
std::vector<Point> InfluxDB::query(const std::string& /*query*/)
{
throw std::runtime_error("InfluxDB query() requires boost");
throw InfluxDBException("InfluxDB::query", "Boost is required");
}
#endif

Expand Down
24 changes: 24 additions & 0 deletions src/InfluxDBException.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
///
/// \author Adam Wegrzynek <[email protected]>
///

#ifndef INFLUXDATA_EXCEPTION_H
#define INFLUXDATA_EXCEPTION_H

#include <stdexcept>
#include <string>

namespace influxdb
{

class InfluxDBException: public std::runtime_error
{

public:
InfluxDBException(const std::string& source, const std::string& message)
: std::runtime_error::runtime_error("influx-cxx [" + source + "]: " + message) {}
};

} // namespace influxdb

#endif // INFLUXDATA_EXCEPTION_H
15 changes: 8 additions & 7 deletions src/InfluxDBFactory.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@
#include <functional>
#include <string>
#include <memory>
#include <map>
#include "UriParser.h"
#include "HTTP.h"
#include <map>
#include "InfluxDBException.h"

#ifdef INFLUXDB_WITH_BOOST
#include "UDP.h"
#include "UnixSocket.h"
#endif

namespace influxdb
namespace influxdb
{

#ifdef INFLUXDB_WITH_BOOST
Expand All @@ -28,11 +29,11 @@ std::unique_ptr<Transport> withUnixSocketTransport(const http::url& uri) {
}
#else
std::unique_ptr<Transport> withUdpTransport(const http::url& /*uri*/) {
throw std::runtime_error("UDP transport requires Boost");
throw InfluxDBException("InfluxDBFactory", "UDP transport requires Boost");
}

std::unique_ptr<Transport> withUnixSocketTransport(const http::url& /*uri*/) {
throw std::runtime_error("Unix socket transport requires Boost");
throw InfluxDBException("InfluxDBFactory", "Unix socket transport requires Boost");
}
#endif

Expand All @@ -58,12 +59,12 @@ std::unique_ptr<Transport> InfluxDBFactory::GetTransport(std::string url) {

http::url parsedUrl = http::ParseHttpUrl(url);
if (parsedUrl.protocol.empty()) {
throw std::runtime_error("Ill-formed URI");
}
throw InfluxDBException("InfluxDBFactory::GetTransport", "Ill-formed URI");
}

auto iterator = map.find(parsedUrl.protocol);
if (iterator == map.end()) {
throw std::runtime_error("Unrecognized backend " + parsedUrl.protocol);
throw InfluxDBException("InfluxDBFactory::GetTransport", "Unrecognized backend " + parsedUrl.protocol);
}

return iterator->second(parsedUrl);
Expand Down
7 changes: 6 additions & 1 deletion src/UDP.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
///

#include "UDP.h"
#include "InfluxDBException.h"
#include <string>

namespace influxdb
Expand All @@ -21,7 +22,11 @@ UDP::UDP(const std::string &hostname, int port) :

void UDP::send(std::string&& message)
{
mSocket.send_to(boost::asio::buffer(message, message.size()), mEndpoint);
try {
mSocket.send_to(boost::asio::buffer(message, message.size()), mEndpoint);
} catch(const boost::system::system_error& e) {
throw InfluxDBException("UDP::send", e.what());
}
}

} // namespace transports
Expand Down
7 changes: 6 additions & 1 deletion src/UnixSocket.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
///

#include "UnixSocket.h"
#include "InfluxDBException.h"
#include <string>

namespace influxdb
Expand All @@ -19,7 +20,11 @@ UnixSocket::UnixSocket(const std::string &socketPath) :

void UnixSocket::send(std::string&& message)
{
mSocket.send_to(boost::asio::buffer(message, message.size()), mEndpoint);
try {
mSocket.send_to(boost::asio::buffer(message, message.size()), mEndpoint);
} catch(const boost::system::system_error& e) {
throw InfluxDBException("UnixSocket::send", e.what());
}
}
#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)

Expand Down
23 changes: 23 additions & 0 deletions test/testFactory.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#define BOOST_TEST_MODULE Test InfluxDB Factory
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

#include "../include/InfluxDBFactory.h"
#include "../src/InfluxDBException.h"

namespace influxdb {
namespace test {


BOOST_AUTO_TEST_CASE(unrecognisedBackend)
{
BOOST_CHECK_THROW(influxdb::InfluxDBFactory::Get("httpz://localhost:8086?db=test"), InfluxDBException);
}

BOOST_AUTO_TEST_CASE(missformatedUrl)
{
BOOST_CHECK_THROW(influxdb::InfluxDBFactory::Get("localhost:8086?db=test"), InfluxDBException);
}

} // namespace test
} // namespace influxdb
12 changes: 12 additions & 0 deletions test/testHttp.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <boost/test/unit_test.hpp>

#include "../include/InfluxDBFactory.h"
#include "../src/InfluxDBException.h"

namespace influxdb {
namespace test {
Expand All @@ -27,5 +28,16 @@ BOOST_AUTO_TEST_CASE(write1)
.addTag("host", "localhost"));
}

BOOST_AUTO_TEST_CASE(writeWrongHost)
{
auto influxdb = influxdb::InfluxDBFactory::Get("http://localhost2:8086?db=test");
BOOST_CHECK_THROW(influxdb->write(Point{"test"}.addField("value", 10)), InfluxDBException);
}

BOOST_AUTO_TEST_CASE(writeNoDb)
{
BOOST_CHECK_THROW(influxdb::InfluxDBFactory::Get("http://localhost:8086"), InfluxDBException);
}

} // namespace test
} // namespace influxdb
2 changes: 1 addition & 1 deletion test/testQuery.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace test {
BOOST_AUTO_TEST_CASE(query1)
{
auto influxdb = influxdb::InfluxDBFactory::Get("http://localhost:8086?db=test");
auto points = influxdb->query("SELECT * from test LIMIT 3");
auto points = influxdb->query("SELECT * from test WHERE host = 'localhost' LIMIT 3");
BOOST_CHECK_EQUAL(points[0].getName(), "test");
BOOST_CHECK_EQUAL(points[1].getName(), "test");
BOOST_CHECK_EQUAL(points[2].getName(), "test");
Expand Down

0 comments on commit 4398f8b

Please sign in to comment.