From 89d872a20cafaa749f386c276629f20827952e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klaim=20=28Jo=C3=ABl=20Lamotte=29?= <142265+Klaim@users.noreply.github.com> Date: Thu, 19 Mar 2026 13:50:26 +0100 Subject: [PATCH 1/4] Uncaught exceptions in transactions execution should always set `"success": false` in JSON output --- libmamba/include/mamba/core/output.hpp | 19 +++++++++++++++++++ libmamba/src/core/transaction.cpp | 3 +++ 2 files changed, 22 insertions(+) diff --git a/libmamba/include/mamba/core/output.hpp b/libmamba/include/mamba/core/output.hpp index f4b7b7d64f..4dc154c11e 100644 --- a/libmamba/include/mamba/core/output.hpp +++ b/libmamba/include/mamba/core/output.hpp @@ -161,6 +161,25 @@ namespace mamba Console(const Context& context); ~Console(); + /** Utilty to set `"success": false` on destruction of this object + when it's destructor is invoked while an exception is in flight. + + This helps avoiding situations where an exception that should be + considered a failure of the overall operation is thrown but + the json is still set with `"success": true`, while it should be `false`, + misleading the testing outputs. + */ + struct JSonFailureOnException + { + ~JSonFailureOnException() + { + if (std::uncaught_exceptions() > 0) + { + Console::instance().json_write({ { "success", false } }); + } + } + }; + private: void json_print(); diff --git a/libmamba/src/core/transaction.cpp b/libmamba/src/core/transaction.cpp index 278ac713f5..6db16fdc5f 100644 --- a/libmamba/src/core/transaction.cpp +++ b/libmamba/src/core/transaction.cpp @@ -367,6 +367,9 @@ namespace mamba bool MTransaction::execute(const Context& ctx, ChannelContext& channel_context, PrefixData& prefix) { + // If an exception exists this function, we must consider the whole operation a failure. + Console::JSonFailureOnException fail_json_on_exception; + // JSON output // back to the top level if any action was required if (!empty()) From 29dcb8daf6f40b780751c819cb819aee8cda825b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klaim=20=28Jo=C3=ABl=20Lamotte=29?= <142265+Klaim@users.noreply.github.com> Date: Thu, 19 Mar 2026 14:09:11 +0100 Subject: [PATCH 2/4] formatting --- libmamba/include/mamba/core/output.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmamba/include/mamba/core/output.hpp b/libmamba/include/mamba/core/output.hpp index 4dc154c11e..f3a81b5e30 100644 --- a/libmamba/include/mamba/core/output.hpp +++ b/libmamba/include/mamba/core/output.hpp @@ -163,7 +163,7 @@ namespace mamba /** Utilty to set `"success": false` on destruction of this object when it's destructor is invoked while an exception is in flight. - + This helps avoiding situations where an exception that should be considered a failure of the overall operation is thrown but the json is still set with `"success": true`, while it should be `false`, From 6084967e4048e47a9516b22c6b773996b437a9b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klaim=20=28Jo=C3=ABl=20Lamotte=29?= <142265+Klaim@users.noreply.github.com> Date: Thu, 19 Mar 2026 14:40:57 +0100 Subject: [PATCH 3/4] fixed typo --- libmamba/include/mamba/core/output.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmamba/include/mamba/core/output.hpp b/libmamba/include/mamba/core/output.hpp index f3a81b5e30..0ef4ef010a 100644 --- a/libmamba/include/mamba/core/output.hpp +++ b/libmamba/include/mamba/core/output.hpp @@ -161,7 +161,7 @@ namespace mamba Console(const Context& context); ~Console(); - /** Utilty to set `"success": false` on destruction of this object + /** Utility to set `"success": false` on destruction of this object when it's destructor is invoked while an exception is in flight. This helps avoiding situations where an exception that should be From 4666fdd3c1b6920302e7066d668c65b1d030c426 Mon Sep 17 00:00:00 2001 From: Julien Jerphanion Date: Thu, 26 Mar 2026 15:52:50 +0100 Subject: [PATCH 4/4] test: Revert spurious changes made to `TestMultiplePkgCaches::test_no_writable_extracted_dir_corrupted` Signed-off-by: Julien Jerphanion --- micromamba/tests/test_pkg_cache.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/micromamba/tests/test_pkg_cache.py b/micromamba/tests/test_pkg_cache.py index 36ad0b9227..e48b820452 100644 --- a/micromamba/tests/test_pkg_cache.py +++ b/micromamba/tests/test_pkg_cache.py @@ -393,16 +393,15 @@ def test_no_writable_extracted_dir_corrupted(self, tmp_home, tmp_root_prefix, tm f"**{file_to_find_in_package}", recursive=True, root_dir=old_cache_dir ) for file in files: - (old_cache_dir / file).unlink() + file.unlink() helpers.recursive_chmod(tmp_cache, 0o500) os.environ["CONDA_PKGS_DIRS"] = f"{tmp_cache}" - # Mamba now handles corrupted extracted directories in read-only caches gracefully - # by extracting to a temporary location, so the operation should succeed - helpers.create( - "-n", "myenv", package_to_check_requirements(), "-vv", "--json", no_dry_run=True - ) + with pytest.raises(subprocess.CalledProcessError): + helpers.create( + "-n", "myenv", package_to_check_requirements(), "-vv", "--json", no_dry_run=True + ) def test_first_writable_extracted_dir_corrupted( self, tmp_home, tmp_root_prefix, tmp_cache, tmp_cache_alt