diff --git a/CHANGES.md b/CHANGES.md index 1b8dc924f..486254b52 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,6 +19,7 @@ - `GltfUtilities::intersectRayGltfModel` now reports a warning when given a model it can't compute the intersection with because it uses required extensions that are not supported. - Errors while loading raster overlays are now logged. Previously, they were silently ignored in many cases. - A raster overlay image failing to load will no longer completely prevent the geometry tile to which it is attached from rendering. Instead, once the raster overlay fails, the geometry tile will be shown without the raster overlay. +- Fixed a bug in the various `catchImmediately` and `catchInMainThread` functions in `CesiumAsync` that prevented use of a mutable lambda. ### v0.39.0 - 2024-09-02 diff --git a/CesiumAsync/include/CesiumAsync/Impl/CatchFunction.h b/CesiumAsync/include/CesiumAsync/Impl/CatchFunction.h index 6045909ad..bbe842635 100644 --- a/CesiumAsync/include/CesiumAsync/Impl/CatchFunction.h +++ b/CesiumAsync/include/CesiumAsync/Impl/CatchFunction.h @@ -22,7 +22,7 @@ struct CatchFunction { } catch (...) { // Make an exception_ptr task, then scheduler to a wrapper around f that // throws it, catches it, and calls f with a reference to it. - auto ptrToException = [f = std::move(f)](std::exception_ptr&& e) { + auto ptrToException = [f = std::move(f)](std::exception_ptr&& e) mutable { try { std::rethrow_exception(e); } catch (std::exception& e) { @@ -52,7 +52,7 @@ struct CatchFunction { } catch (...) { // Make an exception_ptr task, then scheduler to a wrapper around f that // throws it, catches it, and calls f with a reference to it. - auto ptrToException = [f = std::move(f)](std::exception_ptr&& e) { + auto ptrToException = [f = std::move(f)](std::exception_ptr&& e) mutable { try { std::rethrow_exception(e); } catch (std::exception& e) { diff --git a/CesiumAsync/test/TestAsyncSystem.cpp b/CesiumAsync/test/TestAsyncSystem.cpp index 39efaa306..4a2d939bd 100644 --- a/CesiumAsync/test/TestAsyncSystem.cpp +++ b/CesiumAsync/test/TestAsyncSystem.cpp @@ -701,5 +701,23 @@ TEST_CASE("AsyncSystem") { CHECK_THROWS(future.waitInMainThread()); CHECK(!called); } + + SECTION( + "catchImmediately can return a value from a mutable lambda capture") { + auto promise = asyncSystem.createPromise(); + promise.reject(std::runtime_error("Some exception")); + std::string myValue = "value from catch"; + Future future = + promise.getFuture() + .catchImmediately([myValue = std::move(myValue)]( + std::exception&& exception) mutable { + CHECK(std::string(exception.what()) == "Some exception"); + return myValue; + }) + .thenImmediately( + [](std::string&& result) { return std::move(result); }); + std::string result = future.waitInMainThread(); + CHECK(result == "value from catch"); + } } }