Skip to content

Commit 4398f8b

Browse files
authored
Throw custom exceptions (awegrzyn#52)
* 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
1 parent 95d539e commit 4398f8b

14 files changed

+101
-21
lines changed

.travis.yml

+1-4
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,7 @@ script:
2828
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then cmake ..;
2929
else cmake .. -DCMAKE_C_COMPILER=/usr/bin/gcc-7 -DCMAKE_CXX_COMPILER=/usr/bin/g++-7 -DCMAKE_BUILD_TYPE=Debug; fi;
3030
- make -j
31-
- influx -database "test" -execute "select * from test"
32-
- ./bin/testHttp
33-
- influx -database "test" -execute "select * from test"
34-
- ./bin/testQuery
31+
- make test
3532
after_success:
3633
- |
3734
if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ if (Boost_FOUND)
115115
test/testPoint.cxx
116116
test/testHttp.cxx
117117
test/testQuery.cxx
118+
test/testFactory.cxx
118119
)
119120

120121
foreach (test ${TEST_SRCS})

README.md

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66

77
InfluxDB C++ client library
8-
- Writing points
98
- Batch write
109
- Data exploration
1110
- Supported transports

include/InfluxDBFactory.h

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ class InfluxDBFactory
2222
InfluxDBFactory(const InfluxDBFactory&) = delete;
2323

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

2730
private:

src/HTTP.cxx

+8-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
///
44

55
#include "HTTP.h"
6+
#include "InfluxDBException.h"
67
#include <iostream>
78

89
namespace influxdb
@@ -20,11 +21,14 @@ void HTTP::initCurl(const std::string& url)
2021
{
2122
CURLcode globalInitResult = curl_global_init(CURL_GLOBAL_ALL);
2223
if (globalInitResult != CURLE_OK) {
23-
throw std::runtime_error(std::string("cURL init") + curl_easy_strerror(globalInitResult));
24+
throw InfluxDBException("HTTP::initCurl", curl_easy_strerror(globalInitResult));
2425
}
2526

2627
std::string writeUrl = url;
2728
auto position = writeUrl.find("?");
29+
if (position == std::string::npos) {
30+
throw InfluxDBException("HTTP::initCurl", "Database not specified");
31+
}
2832
if (writeUrl.at(position - 1) != '/') {
2933
writeUrl.insert(position, "/write");
3034
} else {
@@ -71,7 +75,7 @@ std::string HTTP::query(const std::string& query)
7175
curl_easy_setopt(readHandle, CURLOPT_WRITEDATA, &buffer);
7276
response = curl_easy_perform(readHandle);
7377
if (response != CURLE_OK) {
74-
throw std::runtime_error(curl_easy_strerror(response));
78+
throw InfluxDBException("HTTP::query", curl_easy_strerror(response));
7579
}
7680
return buffer;
7781
}
@@ -106,10 +110,10 @@ void HTTP::send(std::string&& post)
106110
response = curl_easy_perform(writeHandle);
107111
curl_easy_getinfo(writeHandle, CURLINFO_RESPONSE_CODE, &responseCode);
108112
if (response != CURLE_OK) {
109-
throw std::runtime_error(curl_easy_strerror(response));
113+
throw InfluxDBException("HTTP::send", curl_easy_strerror(response));
110114
}
111115
if (responseCode < 200 || responseCode > 206) {
112-
throw std::runtime_error("Response code : " + std::to_string(responseCode));
116+
throw InfluxDBException("HTTP::send", "Response code: " + std::to_string(responseCode));
113117
}
114118
}
115119

src/HTTP.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ class HTTP : public Transport
2626
~HTTP();
2727

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

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

3436
/// Enable Basic Auth
@@ -39,8 +41,11 @@ class HTTP : public Transport
3941
void enableSsl();
4042
private:
4143

42-
/// Initilizes CURL and all common options
44+
/// Initilizes CURL for writting and common options
45+
/// \throw InfluxDBException if database (?db=) not specified
4346
void initCurl(const std::string& url);
47+
48+
/// Initializes CURL for reading
4449
void initCurlRead(const std::string& url);
4550

4651
/// CURL pointer configured for writting points

src/InfluxDB.cxx

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
///
44

55
#include "InfluxDB.h"
6+
#include "InfluxDBException.h"
67

78
#include <iostream>
89
#include <memory>
@@ -119,7 +120,7 @@ std::vector<Point> InfluxDB::query(const std::string& query)
119120
#else
120121
std::vector<Point> InfluxDB::query(const std::string& /*query*/)
121122
{
122-
throw std::runtime_error("InfluxDB query() requires boost");
123+
throw InfluxDBException("InfluxDB::query", "Boost is required");
123124
}
124125
#endif
125126

src/InfluxDBException.h

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
///
2+
/// \author Adam Wegrzynek <adam.wegrzynek@cern.ch>
3+
///
4+
5+
#ifndef INFLUXDATA_EXCEPTION_H
6+
#define INFLUXDATA_EXCEPTION_H
7+
8+
#include <stdexcept>
9+
#include <string>
10+
11+
namespace influxdb
12+
{
13+
14+
class InfluxDBException: public std::runtime_error
15+
{
16+
17+
public:
18+
InfluxDBException(const std::string& source, const std::string& message)
19+
: std::runtime_error::runtime_error("influx-cxx [" + source + "]: " + message) {}
20+
};
21+
22+
} // namespace influxdb
23+
24+
#endif // INFLUXDATA_EXCEPTION_H

src/InfluxDBFactory.cxx

+8-7
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@
66
#include <functional>
77
#include <string>
88
#include <memory>
9+
#include <map>
910
#include "UriParser.h"
1011
#include "HTTP.h"
11-
#include <map>
12+
#include "InfluxDBException.h"
1213

1314
#ifdef INFLUXDB_WITH_BOOST
1415
#include "UDP.h"
1516
#include "UnixSocket.h"
1617
#endif
1718

18-
namespace influxdb
19+
namespace influxdb
1920
{
2021

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

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

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

5960
http::url parsedUrl = http::ParseHttpUrl(url);
6061
if (parsedUrl.protocol.empty()) {
61-
throw std::runtime_error("Ill-formed URI");
62-
}
62+
throw InfluxDBException("InfluxDBFactory::GetTransport", "Ill-formed URI");
63+
}
6364

6465
auto iterator = map.find(parsedUrl.protocol);
6566
if (iterator == map.end()) {
66-
throw std::runtime_error("Unrecognized backend " + parsedUrl.protocol);
67+
throw InfluxDBException("InfluxDBFactory::GetTransport", "Unrecognized backend " + parsedUrl.protocol);
6768
}
6869

6970
return iterator->second(parsedUrl);

src/UDP.cxx

+6-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
///
44

55
#include "UDP.h"
6+
#include "InfluxDBException.h"
67
#include <string>
78

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

2223
void UDP::send(std::string&& message)
2324
{
24-
mSocket.send_to(boost::asio::buffer(message, message.size()), mEndpoint);
25+
try {
26+
mSocket.send_to(boost::asio::buffer(message, message.size()), mEndpoint);
27+
} catch(const boost::system::system_error& e) {
28+
throw InfluxDBException("UDP::send", e.what());
29+
}
2530
}
2631

2732
} // namespace transports

src/UnixSocket.cxx

+6-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
///
44

55
#include "UnixSocket.h"
6+
#include "InfluxDBException.h"
67
#include <string>
78

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

2021
void UnixSocket::send(std::string&& message)
2122
{
22-
mSocket.send_to(boost::asio::buffer(message, message.size()), mEndpoint);
23+
try {
24+
mSocket.send_to(boost::asio::buffer(message, message.size()), mEndpoint);
25+
} catch(const boost::system::system_error& e) {
26+
throw InfluxDBException("UnixSocket::send", e.what());
27+
}
2328
}
2429
#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
2530

test/testFactory.cxx

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#define BOOST_TEST_MODULE Test InfluxDB Factory
2+
#define BOOST_TEST_DYN_LINK
3+
#include <boost/test/unit_test.hpp>
4+
5+
#include "../include/InfluxDBFactory.h"
6+
#include "../src/InfluxDBException.h"
7+
8+
namespace influxdb {
9+
namespace test {
10+
11+
12+
BOOST_AUTO_TEST_CASE(unrecognisedBackend)
13+
{
14+
BOOST_CHECK_THROW(influxdb::InfluxDBFactory::Get("httpz://localhost:8086?db=test"), InfluxDBException);
15+
}
16+
17+
BOOST_AUTO_TEST_CASE(missformatedUrl)
18+
{
19+
BOOST_CHECK_THROW(influxdb::InfluxDBFactory::Get("localhost:8086?db=test"), InfluxDBException);
20+
}
21+
22+
} // namespace test
23+
} // namespace influxdb

test/testHttp.cxx

+12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <boost/test/unit_test.hpp>
44

55
#include "../include/InfluxDBFactory.h"
6+
#include "../src/InfluxDBException.h"
67

78
namespace influxdb {
89
namespace test {
@@ -27,5 +28,16 @@ BOOST_AUTO_TEST_CASE(write1)
2728
.addTag("host", "localhost"));
2829
}
2930

31+
BOOST_AUTO_TEST_CASE(writeWrongHost)
32+
{
33+
auto influxdb = influxdb::InfluxDBFactory::Get("http://localhost2:8086?db=test");
34+
BOOST_CHECK_THROW(influxdb->write(Point{"test"}.addField("value", 10)), InfluxDBException);
35+
}
36+
37+
BOOST_AUTO_TEST_CASE(writeNoDb)
38+
{
39+
BOOST_CHECK_THROW(influxdb::InfluxDBFactory::Get("http://localhost:8086"), InfluxDBException);
40+
}
41+
3042
} // namespace test
3143
} // namespace influxdb

test/testQuery.cxx

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace test {
1212
BOOST_AUTO_TEST_CASE(query1)
1313
{
1414
auto influxdb = influxdb::InfluxDBFactory::Get("http://localhost:8086?db=test");
15-
auto points = influxdb->query("SELECT * from test LIMIT 3");
15+
auto points = influxdb->query("SELECT * from test WHERE host = 'localhost' LIMIT 3");
1616
BOOST_CHECK_EQUAL(points[0].getName(), "test");
1717
BOOST_CHECK_EQUAL(points[1].getName(), "test");
1818
BOOST_CHECK_EQUAL(points[2].getName(), "test");

0 commit comments

Comments
 (0)