Skip to content

Commit

Permalink
Revert "Do not capture the backtrace for OutOfRange exception. (#194)" (
Browse files Browse the repository at this point in the history
#211)

This reverts commit e5115d3.

Per CBL 5336.
  • Loading branch information
jianminzhao committed Mar 7, 2024
1 parent 6c1e69c commit 87d71c4
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 116 deletions.
13 changes: 2 additions & 11 deletions Fleece/Support/FleeceException.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,8 @@ namespace fleece {
:std::runtime_error(what)
,code(code_)
,err_no(errno_)
{
// The Fleece iterator (of array and dict) throws OutOfRange exception as one moves
// the iterator, operator++ or FLArrayIterator_Next, for instances, beyond the
// end of the array. Although the exception is caught inside Fleece and the
// client gets return of false, the effort to capture the backtrace can be
// very significant as shown in performance profilings. And, the backtrace is not
// used anyway.
if (code_ != OutOfRange) {
backtrace = Backtrace::capture(2);
}
}
,backtrace(Backtrace::capture(2))
{ }


__cold
Expand Down
105 changes: 0 additions & 105 deletions Tests/ValueTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -259,109 +259,4 @@ namespace fleece {
// (calling FLDictIterator_Next would be illegal)
FLDoc_Release(doc);
}

TEST_CASE("Array Iterators") {
FLDoc doc = nullptr;
SECTION("Empty Array") {
doc = FLDoc_FromJSON("[]"_sl, nullptr);
}
SECTION("Non Empty Array") {
doc = FLDoc_FromJSON("[1]"_sl, nullptr);
}
REQUIRE(doc);

FLValue val = FLDoc_GetRoot(doc);
FLArray arr = FLValue_AsArray(val);
REQUIRE(arr);
Array::iterator iter = Array::iterator((Array*)arr);

bool caughtException = false;
bool capturedBacktrace = true;

// No exception with typical loop.
try {
for (; iter; ++iter);
} catch (...) {
caughtException = true;
}
CHECK(!caughtException);

caughtException = false;
// ++iter will throw if already at the end.
// OutOfRange exception should not contain the backtrace.
try {
++iter;
} catch (const FleeceException& exc) {
if (exc.code == (int)kFLOutOfRange) {
caughtException = true;
capturedBacktrace = !!exc.backtrace;
}
}
CHECK((caughtException && !capturedBacktrace));

// FL Itarator
FLArrayIterator flIter;
FLArrayIterator_Begin(arr, &flIter);
FLValue value;
while (NULL != (value = FLArrayIterator_GetValue(&flIter))) {
FLArrayIterator_Next(&flIter);
}
// Calling Next is okay. It will trigger exception but we won't try to capture the backtrace.
CHECK(!FLArrayIterator_Next(&flIter));

FLDoc_Release(doc);
}

TEST_CASE("Dict Iterators") {
FLDoc doc = nullptr;
SECTION("Empty Dict") {
doc = FLDoc_FromJSON("{}"_sl, nullptr);
}
SECTION("Non Empty Dict") {
doc = FLDoc_FromJSON(R"({"key": 1})"_sl, nullptr);
}
REQUIRE(doc);

FLValue val = FLDoc_GetRoot(doc);
FLDict dict = FLValue_AsDict(val);
REQUIRE(dict);
Dict::iterator iter = Dict::iterator((Dict*)dict);

bool caughtException = false;
bool capturedBacktrace = true;

// No exception with typical loop pattern.
try {
for (; iter; ++iter);
} catch (...) {
caughtException = true;
}
CHECK(!caughtException);

caughtException = false;
// ++iter will throw if already at the end.
// OutOfRange exception should contain the backtrace.
try {
++iter;
} catch (const FleeceException& exc) {
if (exc.code == (int)kFLOutOfRange) {
caughtException = true;
capturedBacktrace = !!exc.backtrace;
}
}
CHECK((caughtException && !capturedBacktrace));

// FL Itarator
FLDictIterator flIter;
FLDictIterator_Begin(dict, &flIter);
FLValue value;
while (NULL != (value = FLDictIterator_GetValue(&flIter))) {
FLDictIterator_Next(&flIter);
}
// Calling Next is okay. It will trigger exception but we won't try to capture the backtrace.
// Cannot assert it directly. Internally, it uses Dict::iterator::operator++().
CHECK(!FLDictIterator_Next(&flIter));

FLDoc_Release(doc);
}
}

0 comments on commit 87d71c4

Please sign in to comment.