зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1709352 - Allow QMResult errors to use existing stack id and to increase the frame id during error propagation; r=dom-storage-reviewers,asuth,glandium
Differential Revision: https://phabricator.services.mozilla.com/D114243
This commit is contained in:
Родитель
01123f15c4
Коммит
c06f56c861
|
@ -17,6 +17,39 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
// Allow QMResult errors to use existing stack id and to increase the frame id
|
||||
// during error propagation.
|
||||
template <>
|
||||
class MOZ_MUST_USE_TYPE GenericErrorResult<QMResult> {
|
||||
QMResult mErrorValue;
|
||||
|
||||
template <typename V, typename E2>
|
||||
friend class Result;
|
||||
|
||||
public:
|
||||
explicit GenericErrorResult(const QMResult& aErrorValue)
|
||||
: mErrorValue(aErrorValue) {
|
||||
MOZ_ASSERT(NS_FAILED(aErrorValue.NSResult()));
|
||||
}
|
||||
|
||||
explicit GenericErrorResult(QMResult&& aErrorValue)
|
||||
: mErrorValue(std::move(aErrorValue)) {
|
||||
MOZ_ASSERT(NS_FAILED(aErrorValue.NSResult()));
|
||||
}
|
||||
|
||||
explicit GenericErrorResult(const QMResult& aErrorValue,
|
||||
const ErrorPropagationTag&)
|
||||
: GenericErrorResult(aErrorValue.Propagate()) {}
|
||||
|
||||
explicit GenericErrorResult(QMResult&& aErrorValue,
|
||||
const ErrorPropagationTag&)
|
||||
: GenericErrorResult(aErrorValue.Propagate()) {}
|
||||
|
||||
operator QMResult() const { return mErrorValue; }
|
||||
|
||||
operator nsresult() const { return mErrorValue.NSResult(); }
|
||||
};
|
||||
|
||||
inline Result<Ok, QMResult> ToResult(const QMResult& aValue) {
|
||||
if (NS_FAILED(aValue.NSResult())) {
|
||||
return Err(aValue);
|
||||
|
|
|
@ -1076,6 +1076,10 @@ class MOZ_MUST_USE_TYPE GenericErrorResult<mozilla::ipc::IPCResult> {
|
|||
MOZ_ASSERT(!aErrorValue);
|
||||
}
|
||||
|
||||
GenericErrorResult(mozilla::ipc::IPCResult aErrorValue,
|
||||
const ErrorPropagationTag&)
|
||||
: GenericErrorResult(aErrorValue) {}
|
||||
|
||||
operator mozilla::ipc::IPCResult() const { return mErrorValue; }
|
||||
};
|
||||
|
||||
|
|
|
@ -79,3 +79,24 @@ TEST(DOM_Quota_QMResult, ToResult)
|
|||
ASSERT_EQ(err.NSResult(), NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DOM_Quota_QMResult, ErrorPropagation)
|
||||
{
|
||||
Result<Ok, QMResult> valOrErr1 = ToResult(ToQMResult(NS_ERROR_FAILURE));
|
||||
const auto& err1 = valOrErr1.inspectErr();
|
||||
ASSERT_EQ(err1.StackId(), 7u);
|
||||
ASSERT_EQ(err1.FrameId(), 1u);
|
||||
ASSERT_EQ(err1.NSResult(), NS_ERROR_FAILURE);
|
||||
|
||||
Result<Ok, QMResult> valOrErr2 = valOrErr1.propagateErr();
|
||||
const auto& err2 = valOrErr2.inspectErr();
|
||||
ASSERT_EQ(err2.StackId(), 7u);
|
||||
ASSERT_EQ(err2.FrameId(), 2u);
|
||||
ASSERT_EQ(err2.NSResult(), NS_ERROR_FAILURE);
|
||||
|
||||
Result<Ok, QMResult> valOrErr3 = valOrErr2.propagateErr();
|
||||
const auto& err3 = valOrErr3.inspectErr();
|
||||
ASSERT_EQ(err3.StackId(), 7u);
|
||||
ASSERT_EQ(err3.FrameId(), 3u);
|
||||
ASSERT_EQ(err3.NSResult(), NS_ERROR_FAILURE);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,15 @@ namespace mozilla {
|
|||
*/
|
||||
struct Ok {};
|
||||
|
||||
/**
|
||||
* A tag used to differentiate between GenericErrorResult created by the Err
|
||||
* function (completely new error) and GenericErrorResult created by the
|
||||
* Result::propagateErr function (propagated error). This can be used to track
|
||||
* error propagation and eventually produce error stacks for logging/debugging
|
||||
* purposes.
|
||||
*/
|
||||
struct ErrorPropagationTag {};
|
||||
|
||||
template <typename E>
|
||||
class GenericErrorResult;
|
||||
template <typename V, typename E>
|
||||
|
@ -563,7 +572,7 @@ class MOZ_MUST_USE_TYPE Result final {
|
|||
*/
|
||||
constexpr GenericErrorResult<E> propagateErr() {
|
||||
MOZ_ASSERT(isErr());
|
||||
return GenericErrorResult<E>{mImpl.unwrapErr()};
|
||||
return GenericErrorResult<E>{mImpl.unwrapErr(), ErrorPropagationTag{}};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -748,6 +757,12 @@ class MOZ_MUST_USE_TYPE GenericErrorResult {
|
|||
|
||||
explicit constexpr GenericErrorResult(E&& aErrorValue)
|
||||
: mErrorValue(std::move(aErrorValue)) {}
|
||||
|
||||
constexpr GenericErrorResult(const E& aErrorValue, const ErrorPropagationTag&)
|
||||
: GenericErrorResult(aErrorValue) {}
|
||||
|
||||
constexpr GenericErrorResult(E&& aErrorValue, const ErrorPropagationTag&)
|
||||
: GenericErrorResult(std::move(aErrorValue)) {}
|
||||
};
|
||||
|
||||
template <typename E>
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
struct ErrorPropagationTag;
|
||||
|
||||
// Allow nsresult errors to automatically convert to nsresult values, so MOZ_TRY
|
||||
// can be used in XPCOM methods with Result<T, nserror> results.
|
||||
template <>
|
||||
|
@ -30,6 +32,9 @@ class MOZ_MUST_USE_TYPE GenericErrorResult<nsresult> {
|
|||
MOZ_ASSERT(NS_FAILED(aErrorValue));
|
||||
}
|
||||
|
||||
GenericErrorResult(nsresult aErrorValue, const ErrorPropagationTag&)
|
||||
: GenericErrorResult(aErrorValue) {}
|
||||
|
||||
operator nsresult() const { return mErrorValue; }
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче