diff options
author | Pierlauro Sciarelli <pierlauro.sciarelli@mongodb.com> | 2020-11-16 18:04:16 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-11-16 19:43:11 +0000 |
commit | aa2b7d3eb58690778f8ea378afaa471beb65d491 (patch) | |
tree | 8a5a3a239db5f2fc7103379c2c900a8673cb9486 | |
parent | e1e8ea257b835c4d8e130205a2fd8297bcccbd47 (diff) | |
download | mongo-aa2b7d3eb58690778f8ea378afaa471beb65d491.tar.gz |
SERVER-52741 Avoid invariant when trying to get optional ErrorExtraInfo
-rw-r--r-- | src/mongo/base/status.h | 18 | ||||
-rw-r--r-- | src/mongo/base/status_test.cpp | 8 | ||||
-rw-r--r-- | src/mongo/util/assert_util.h | 8 |
3 files changed, 22 insertions, 12 deletions
diff --git a/src/mongo/base/status.h b/src/mongo/base/status.h index 0b9d1fc1f6e..4d6e332f28a 100644 --- a/src/mongo/base/status.h +++ b/src/mongo/base/status.h @@ -168,27 +168,31 @@ public: /** * Returns the generic ErrorExtraInfo if present. */ - const ErrorExtraInfo* extraInfo() const { - return isOK() ? nullptr : _error->extra.get(); + const std::shared_ptr<const ErrorExtraInfo> extraInfo() const { + return isOK() ? nullptr : _error->extra; } /** * Returns a specific subclass of ErrorExtraInfo if the error code matches that type. */ template <typename T> - const T* extraInfo() const { + std::shared_ptr<const T> extraInfo() const { MONGO_STATIC_ASSERT(std::is_base_of<ErrorExtraInfo, T>()); MONGO_STATIC_ASSERT(std::is_same<error_details::ErrorExtraInfoFor<T::code>, T>()); if (isOK()) - return nullptr; + return {}; if (code() != T::code) - return nullptr; + return {}; + + if (!_error->extra) { + invariant(!ErrorCodes::mustHaveExtraInfo(_error->code)); + return {}; + } // Can't use checked_cast due to include cycle. - invariant(_error->extra); dassert(dynamic_cast<const T*>(_error->extra.get())); - return static_cast<const T*>(_error->extra.get()); + return std::static_pointer_cast<const T>(_error->extra); } std::string toString() const; diff --git a/src/mongo/base/status_test.cpp b/src/mongo/base/status_test.cpp index 73cb1766907..4e2582597bf 100644 --- a/src/mongo/base/status_test.cpp +++ b/src/mongo/base/status_test.cpp @@ -326,6 +326,14 @@ TEST(ErrorExtraInfo, OptionalExtraInfoStatusParserWorks) { ASSERT_EQ(status.extraInfo<OptionalErrorExtraInfoExample>()->data, 123); } +TEST(ErrorExtraInfo, MissingOptionalExtraInfoStatus) { + OptionalErrorExtraInfoExample::EnableParserForTest whenInScope; + const auto status = Status(ErrorCodes::ForTestingOptionalErrorExtraInfo, ""); + ASSERT_EQ(status, ErrorCodes::ForTestingOptionalErrorExtraInfo); + ASSERT_FALSE(status.extraInfo()); + ASSERT_FALSE(status.extraInfo<OptionalErrorExtraInfoExample>()); +} + TEST(ErrorExtraInfo, TypedConstructorWorks) { const auto status = Status(ErrorExtraInfoExample(123), ""); ASSERT_EQ(status, ErrorCodes::ForTestingErrorExtraInfo); diff --git a/src/mongo/util/assert_util.h b/src/mongo/util/assert_util.h index 0e2558cf093..b44dceccafa 100644 --- a/src/mongo/util/assert_util.h +++ b/src/mongo/util/assert_util.h @@ -62,8 +62,6 @@ public: }; extern AssertionCount assertionCount; - - class DBException; std::string causedBy(const DBException& e); std::string causedBy(const std::string& e); @@ -117,7 +115,7 @@ public: /** * Returns the generic ErrorExtraInfo if present. */ - const ErrorExtraInfo* extraInfo() const { + const std::shared_ptr<const ErrorExtraInfo> extraInfo() const { return _status.extraInfo(); } @@ -125,7 +123,7 @@ public: * Returns a specific subclass of ErrorExtraInfo if the error code matches that type. */ template <typename ErrorDetail> - const ErrorDetail* extraInfo() const { + std::shared_ptr<const ErrorDetail> extraInfo() const { return _status.extraInfo<ErrorDetail>(); } @@ -189,7 +187,7 @@ public: // This is only a template to enable SFINAE. It will only be instantiated with the default // value. template <ErrorCodes::Error code_copy = kCode> - const ErrorExtraInfoFor<code_copy>* operator->() const { + std::shared_ptr<const ErrorExtraInfoFor<code_copy>> operator->() const { MONGO_STATIC_ASSERT(code_copy == kCode); return this->template extraInfo<ErrorExtraInfoFor<kCode>>(); } |