Skip to content

Commit c6028f8

Browse files
committed
CXX-477 include error information in exceptions
1 parent 6fd9782 commit c6028f8

File tree

13 files changed

+182
-41
lines changed

13 files changed

+182
-41
lines changed

src/mongocxx/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ set(mongocxx_sources
2424
collection.cpp
2525
cursor.cpp
2626
database.cpp
27+
exception/base.cpp
2728
instance.cpp
2829
model/delete_many.cpp
2930
model/delete_one.cpp

src/mongocxx/collection.cpp

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,38 +12,40 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
#include <mongocxx/collection.hpp>
16+
1517
#include <cstdint>
18+
#include <utility>
19+
#include <tuple>
1620

1721
#include <bsoncxx/builder/stream/document.hpp>
1822
#include <bsoncxx/builder/stream/helpers.hpp>
23+
#include <bsoncxx/stdx/make_unique.hpp>
24+
#include <bsoncxx/stdx/optional.hpp>
1925
#include <bsoncxx/types.hpp>
2026

21-
#include <mongocxx/private/client.hpp>
22-
#include <mongocxx/private/collection.hpp>
23-
#include <mongocxx/private/database.hpp>
24-
#include <mongocxx/private/pipeline.hpp>
25-
#include <mongocxx/private/bulk_write.hpp>
26-
#include <mongocxx/private/read_preference.hpp>
27-
#include <mongocxx/private/write_concern.hpp>
28-
#include <mongocxx/write_concern.hpp>
29-
#include <mongocxx/collection.hpp>
3027
#include <mongocxx/client.hpp>
3128
#include <mongocxx/exception/bulk_write.hpp>
3229
#include <mongocxx/exception/operation.hpp>
30+
#include <mongocxx/exception/query.hpp>
3331
#include <mongocxx/exception/write.hpp>
3432
#include <mongocxx/model/write.hpp>
33+
#include <mongocxx/private/bulk_write.hpp>
34+
#include <mongocxx/private/client.hpp>
35+
#include <mongocxx/private/collection.hpp>
36+
#include <mongocxx/private/database.hpp>
3537
#include <mongocxx/private/libbson.hpp>
3638
#include <mongocxx/private/libmongoc.hpp>
39+
#include <mongocxx/private/pipeline.hpp>
40+
#include <mongocxx/private/read_preference.hpp>
41+
#include <mongocxx/private/write_concern.hpp>
3742
#include <mongocxx/result/bulk_write.hpp>
3843
#include <mongocxx/result/delete.hpp>
3944
#include <mongocxx/result/insert_many.hpp>
4045
#include <mongocxx/result/insert_one.hpp>
4146
#include <mongocxx/result/replace_one.hpp>
4247
#include <mongocxx/result/update.hpp>
43-
44-
#include <bsoncxx/stdx/optional.hpp>
45-
#include <bsoncxx/stdx/make_unique.hpp>
46-
48+
#include <mongocxx/write_concern.hpp>
4749

4850
namespace {
4951
enum class cursor_flag : uint32_t {
@@ -89,7 +91,7 @@ bsoncxx::stdx::optional<result::bulk_write> collection::bulk_write(
8991
bson_error_t error;
9092

9193
if (!libmongoc::bulk_operation_execute(b, reply.bson(), &error)) {
92-
throw exception::bulk_write();
94+
throw exception::bulk_write(reply.steal(), std::make_tuple(error.message, error.code));
9395
}
9496

9597
result::bulk_write result(reply.steal());
@@ -326,7 +328,7 @@ bsoncxx::stdx::optional<bsoncxx::document::value> collection::find_one_and_repla
326328
rd == options::return_document::k_after, reply.bson(), &error);
327329

328330
if (!r) {
329-
throw exception::operation();
331+
throw exception::write(std::move(_impl->gle()), std::make_tuple(error.message, error.code));
330332
}
331333

332334
bsoncxx::document::view result = reply.view();
@@ -361,7 +363,7 @@ bsoncxx::stdx::optional<bsoncxx::document::value> collection::find_one_and_updat
361363
rd == options::return_document::k_after, reply.bson(), &error);
362364

363365
if (!r) {
364-
throw exception::operation();
366+
throw exception::write(std::move(_impl->gle()), std::make_tuple(error.message, error.code));
365367
}
366368

367369
bsoncxx::document::view result = reply.view();
@@ -390,7 +392,7 @@ bsoncxx::stdx::optional<bsoncxx::document::value> collection::find_one_and_delet
390392
true, false, false, reply.bson(), &error);
391393

392394
if (!r) {
393-
throw exception::operation();
395+
throw exception::write(std::move(_impl->gle()), std::make_tuple(error.message, error.code));
394396
}
395397

396398
bsoncxx::document::view result = reply.view();
@@ -418,7 +420,7 @@ std::int64_t collection::count(bsoncxx::document::view filter, const options::co
418420
options.skip().value_or(0), options.limit().value_or(0), rp_ptr, &error);
419421

420422
if (result < 0) {
421-
throw exception::operation();
423+
throw exception::query(std::make_tuple(error.message, error.code));
422424
}
423425

424426
return result;
@@ -433,7 +435,7 @@ bsoncxx::document::value collection::create_index(bsoncxx::document::view keys,
433435
libmongoc::collection_create_index(_impl->collection_t, bson_keys.bson(), nullptr, &error);
434436

435437
if (!result) {
436-
throw exception::operation();
438+
throw exception::operation(std::make_tuple(error.message, error.code));
437439
}
438440

439441
// TODO: return the response from the server, this is not possible now due to the way
@@ -474,7 +476,7 @@ void collection::drop() {
474476
auto result = libmongoc::collection_drop(_impl->collection_t, &error);
475477

476478
if (!result) {
477-
throw exception::operation();
479+
throw exception::operation(std::make_tuple(error.message, error.code));
478480
}
479481
}
480482

src/mongocxx/collection.hpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ class MONGOCXX_API collection {
9999
/// Optional arguments, see mongocxx::options::aggregate.
100100
///
101101
/// @return A mongocxx::cursor with the results.
102-
/// @throws exception::operation if the aggregation fails.
102+
/// @throws
103+
/// If the operation failed, the returned cursor will throw an exception::query
104+
/// when it is iterated.
103105
///
104106
/// @see http://docs.mongodb.org/manual/reference/command/aggregate/
105107
///
@@ -184,7 +186,7 @@ class MONGOCXX_API collection {
184186
/// Optional arguments, see mongocxx::options::count.
185187
///
186188
/// @return The count of the documents that matched the filter.
187-
/// @throws exception::operation if the count operation fails.
189+
/// @throws exception::query if the count operation fails.
188190
///
189191
/// @see http://docs.mongodb.org/manual/reference/command/count/
190192
///
@@ -258,7 +260,9 @@ class MONGOCXX_API collection {
258260
/// Optional arguments, see options::distinct.
259261
///
260262
/// @return Cursor having the distinct values for the specified field, a driver::cursor.
261-
/// @throws operation_exception if the distinct operation fails.
263+
/// @throws
264+
/// If the operation failed, the returned cursor will throw exception::query
265+
/// when it is iterated.
262266
///
263267
/// @see http://docs.mongodb.org/manual/reference/command/distinct/
264268
///
@@ -286,7 +290,9 @@ class MONGOCXX_API collection {
286290
/// Optional arguments, see options::find
287291
///
288292
/// @return Cursor with the matching documents from the collection, a driver::cursor.
289-
/// @throws exception::operation when the operation fails.
293+
/// @throws
294+
/// If the find failed, the returned cursor will throw exception::query when it
295+
/// is iterated.
290296
///
291297
/// @see http://docs.mongodb.org/manual/core/read-operations-introduction/
292298
///
@@ -305,7 +311,7 @@ class MONGOCXX_API collection {
305311
/// Optional arguments, see options::find
306312
///
307313
/// @return An optional document that matched the filter.
308-
/// @throws exception::operation if the operation fails.
314+
/// @throws exception::query if the operation fails.
309315
///
310316
/// @see http://docs.mongodb.org/manual/core/read-operations-introduction/
311317
///
@@ -323,7 +329,7 @@ class MONGOCXX_API collection {
323329
/// Optional arguments, see options::find_one_and_delete
324330
///
325331
/// @return The document that was deleted.
326-
/// @throws exception::operation if the operation fails.
332+
/// @throws exception::write if the operation fails.
327333
///
328334
bsoncxx::stdx::optional<bsoncxx::document::value> find_one_and_delete(
329335
bsoncxx::document::view filter,
@@ -342,7 +348,7 @@ class MONGOCXX_API collection {
342348
/// Optional arguments, see options::find_one_and_replace.
343349
///
344350
/// @return The original or replaced document.
345-
/// @throws exception::operation if the operation fails.
351+
/// @throws exception::write if the operation fails.
346352
///
347353
bsoncxx::stdx::optional<bsoncxx::document::value> find_one_and_replace(
348354
bsoncxx::document::view filter,
@@ -362,7 +368,7 @@ class MONGOCXX_API collection {
362368
/// Optional arguments, see options::find_one_and_update.
363369
///
364370
/// @return The original or updated document.
365-
/// @throws exception::operation when the operation fails.
371+
/// @throws exception::write when the operation fails.
366372
///
367373
bsoncxx::stdx::optional<bsoncxx::document::value> find_one_and_update(
368374
bsoncxx::document::view filter,

src/mongocxx/cursor.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414

1515
#include <cstdint>
1616
#include <memory>
17+
#include <string>
18+
#include <tuple>
1719

1820
#include <bson.h>
1921

2022
#include <mongocxx/cursor.hpp>
2123

22-
#include <mongocxx/exception/operation.hpp>
24+
#include <mongocxx/exception/query.hpp>
2325
#include <mongocxx/private/cursor.hpp>
2426
#include <mongocxx/private/libmongoc.hpp>
2527

@@ -47,8 +49,7 @@ cursor::iterator& cursor::iterator::operator++() {
4749
if (libmongoc::cursor_next(_cursor->_impl->cursor_t, &out)) {
4850
_doc = bsoncxx::document::view(bson_get_data(out), out->len);
4951
} else if (libmongoc::cursor_error(_cursor->_impl->cursor_t, &error)) {
50-
// TODO: put cursor error message in here.
51-
throw exception::operation();
52+
throw exception::query(std::make_tuple(error.message, error.code));
5253
} else {
5354
_cursor = nullptr;
5455
};

src/mongocxx/database.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
#include <mongocxx/database.hpp>
1616

17+
#include <utility>
18+
19+
#include <bsoncxx/stdx/make_unique.hpp>
20+
1721
#include <mongocxx/client.hpp>
1822
#include <mongocxx/exception/operation.hpp>
1923
#include <mongocxx/private/database.hpp>
@@ -22,8 +26,6 @@
2226
#include <mongocxx/private/libbson.hpp>
2327
#include <mongocxx/private/libmongoc.hpp>
2428

25-
#include <bsoncxx/stdx/make_unique.hpp>
26-
2729
namespace mongocxx {
2830
MONGOCXX_INLINE_NAMESPACE_BEGIN
2931

@@ -60,7 +62,7 @@ bsoncxx::document::value database::command(bsoncxx::document::view command) {
6062
);
6163

6264
if (!result)
63-
throw exception::operation();
65+
throw exception::operation(std::move(reply_bson.steal()));
6466

6567
return reply_bson.steal();
6668
}

src/mongocxx/exception/authentication.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ namespace mongocxx {
2222
MONGOCXX_INLINE_NAMESPACE_BEGIN
2323
namespace exception {
2424

25-
class MONGOCXX_API authentication : public operation {};
25+
class MONGOCXX_API authentication : public base {
26+
public:
27+
using base::base;
28+
};
2629

2730
} // namespace exception
2831
MONGOCXX_INLINE_NAMESPACE_END

src/mongocxx/exception/base.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2015 MongoDB Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <mongocxx/exception/base.hpp>
16+
17+
#include <utility>
18+
19+
namespace mongocxx {
20+
MONGOCXX_INLINE_NAMESPACE_BEGIN
21+
namespace exception {
22+
23+
base::base(bsoncxx::document::value raw_server_error)
24+
: _raw_server_error(std::move(raw_server_error))
25+
{}
26+
27+
base::base(error_and_code_type error_and_code)
28+
: _error_and_code(std::move(error_and_code))
29+
{}
30+
31+
base::base(bsoncxx::document::value raw_server_error,
32+
error_and_code_type error_and_code)
33+
: _raw_server_error(std::move(raw_server_error))
34+
, _error_and_code(std::move(error_and_code))
35+
{}
36+
37+
const stdx::optional<bsoncxx::document::value>& base::raw_server_error() const {
38+
return _raw_server_error;
39+
}
40+
41+
stdx::optional<bsoncxx::document::value>& base::raw_server_error() {
42+
return _raw_server_error;
43+
}
44+
45+
const stdx::optional<error_and_code_type>& base::error_and_code() const {
46+
return _error_and_code;
47+
}
48+
49+
stdx::optional<error_and_code_type>& base::error_and_code() {
50+
return _error_and_code;
51+
}
52+
53+
} // namespace exception
54+
MONGOCXX_INLINE_NAMESPACE_END
55+
} // namespace mongocxx

src/mongocxx/exception/base.hpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,48 @@
1616

1717
#include <mongocxx/config/prelude.hpp>
1818

19+
#include <cstdint>
1920
#include <exception>
21+
#include <tuple>
22+
23+
#include <bsoncxx/document/value.hpp>
24+
#include <bsoncxx/document/view.hpp>
25+
#include <bsoncxx/stdx/optional.hpp>
26+
27+
#include <mongocxx/stdx.hpp>
2028

2129
namespace mongocxx {
2230
MONGOCXX_INLINE_NAMESPACE_BEGIN
2331
namespace exception {
2432

25-
class MONGOCXX_API base : public std::exception {};
33+
using error_and_code_type = std::tuple<std::string, std::int32_t>;
34+
35+
class MONGOCXX_API base : virtual public std::exception {
36+
public:
37+
base(bsoncxx::document::value raw_server_error);
38+
base(error_and_code_type error_and_code);
39+
40+
base(
41+
bsoncxx::document::value raw_server_error,
42+
error_and_code_type error_and_code
43+
);
44+
45+
///
46+
/// @returns The raw server error, if it is available.
47+
///
48+
const stdx::optional<bsoncxx::document::value>& raw_server_error() const;
49+
stdx::optional<bsoncxx::document::value>& raw_server_error();
50+
51+
///
52+
/// @returns The error message and code, if it is available.
53+
///
54+
const stdx::optional<error_and_code_type>& error_and_code() const;
55+
stdx::optional<error_and_code_type>& error_and_code();
56+
57+
private:
58+
stdx::optional<bsoncxx::document::value> _raw_server_error{};
59+
stdx::optional<error_and_code_type> _error_and_code{};
60+
};
2661

2762
} // namespace exception
2863
MONGOCXX_INLINE_NAMESPACE_END

src/mongocxx/exception/bulk_write.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,18 @@
1616

1717
#include <mongocxx/config/prelude.hpp>
1818

19-
#include <mongocxx/exception/write.hpp>
19+
#include <bsoncxx/document/value.hpp>
20+
21+
#include <mongocxx/exception/operation.hpp>
2022

2123
namespace mongocxx {
2224
MONGOCXX_INLINE_NAMESPACE_BEGIN
2325
namespace exception {
2426

25-
class MONGOCXX_API bulk_write : public write {};
27+
class MONGOCXX_API bulk_write : public operation {
28+
public:
29+
using operation::operation;
30+
};
2631

2732
} // namespace exception
2833
MONGOCXX_INLINE_NAMESPACE_END

0 commit comments

Comments
 (0)