From 3da5588ce6c35d15407e53a7078f6627f3469855 Mon Sep 17 00:00:00 2001 From: Cole Helbling Date: Thu, 12 Feb 2026 08:38:54 -0800 Subject: [PATCH 1/4] filetransfer: mark enqueueFileTransfer() as noexcept --- src/libstore/filetransfer.cc | 5 +++-- src/libstore/include/nix/store/filetransfer.hh | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index 4d513ec3714c..eac50aba1b78 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -1046,7 +1046,8 @@ struct curlFileTransfer : public FileTransfer return ItemHandle(item.get_ptr()); } - ItemHandle enqueueFileTransfer(const FileTransferRequest & request, Callback callback) override + ItemHandle + enqueueFileTransfer(const FileTransferRequest & request, Callback callback) noexcept override { /* Handle s3:// URIs by converting to HTTPS and optionally adding auth */ if (request.uri.scheme() == "s3") { @@ -1133,7 +1134,7 @@ void FileTransferRequest::setupForS3() #endif } -std::future FileTransfer::enqueueFileTransfer(const FileTransferRequest & request) +std::future FileTransfer::enqueueFileTransfer(const FileTransferRequest & request) noexcept { auto promise = std::make_shared>(); enqueueFileTransfer(request, {[promise](std::future fut) { diff --git a/src/libstore/include/nix/store/filetransfer.hh b/src/libstore/include/nix/store/filetransfer.hh index 1bf5dd80fbe6..272bc13218d7 100644 --- a/src/libstore/include/nix/store/filetransfer.hh +++ b/src/libstore/include/nix/store/filetransfer.hh @@ -354,14 +354,14 @@ public: * exception. */ virtual ItemHandle - enqueueFileTransfer(const FileTransferRequest & request, Callback callback) = 0; + enqueueFileTransfer(const FileTransferRequest & request, Callback callback) noexcept = 0; /** * Unpause a transfer that has been previously paused by a dataCallback. */ virtual void unpauseTransfer(ItemHandle handle) = 0; - std::future enqueueFileTransfer(const FileTransferRequest & request); + std::future enqueueFileTransfer(const FileTransferRequest & request) noexcept; /** * Synchronously download a file. From cd9144cb85667a190ff17fb8b614c180a46c8061 Mon Sep 17 00:00:00 2001 From: Cole Helbling Date: Thu, 12 Feb 2026 08:53:04 -0800 Subject: [PATCH 2/4] filetransfer: handle exceptions thrown from enqueueItem --- src/libstore/filetransfer.cc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index eac50aba1b78..eee8afa2b50c 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -1053,10 +1053,22 @@ struct curlFileTransfer : public FileTransfer if (request.uri.scheme() == "s3") { auto modifiedRequest = request; modifiedRequest.setupForS3(); - return enqueueItem(make_ref(*this, std::move(modifiedRequest), std::move(callback))); + auto item = make_ref(*this, std::move(modifiedRequest), std::move(callback)); + try { + return enqueueItem(item); + } catch (const nix::Error & e) { + item->fail(e); + return ItemHandle(item.get_ptr()); + } } - return enqueueItem(make_ref(*this, request, std::move(callback))); + auto item = make_ref(*this, request, std::move(callback)); + try { + return enqueueItem(item); + } catch (const nix::Error & e) { + item->fail(e); + return ItemHandle(item.get_ptr()); + } } void unpauseTransfer(std::weak_ptr item) From 3f3e4647cdbbd4db264620558f14aa00814b493e Mon Sep 17 00:00:00 2001 From: Cole Helbling Date: Mon, 30 Mar 2026 13:01:54 -0700 Subject: [PATCH 3/4] fixup: catch BaseError instead of Error That way it catches both nix::Error as well as nix::Interrupted. --- src/libstore/filetransfer.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index eee8afa2b50c..2cad49109a2d 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -1056,7 +1056,10 @@ struct curlFileTransfer : public FileTransfer auto item = make_ref(*this, std::move(modifiedRequest), std::move(callback)); try { return enqueueItem(item); - } catch (const nix::Error & e) { + } catch (const nix::BaseError & e) { + // NOTE(cole-h): catches both nix::Error and nix::Interrupted -- enqueueItem calls + // writeFull which may throw nix::Interrupted, and the rest of enqueueItem may throw + // nix::Error item->fail(e); return ItemHandle(item.get_ptr()); } @@ -1065,7 +1068,10 @@ struct curlFileTransfer : public FileTransfer auto item = make_ref(*this, request, std::move(callback)); try { return enqueueItem(item); - } catch (const nix::Error & e) { + } catch (const nix::BaseError & e) { + // NOTE(cole-h): catches both nix::Error and nix::Interrupted -- enqueueItem calls + // writeFull which may throw nix::Interrupted, and the rest of enqueueItem may throw + // nix::Error item->fail(e); return ItemHandle(item.get_ptr()); } From c526da920ed4d7916107869b7cf9828c9d67d59f Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Wed, 8 Apr 2026 10:11:36 -0700 Subject: [PATCH 4/4] Refactor enqueueFileTransfer --- src/libstore/filetransfer.cc | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index 2cad49109a2d..b85649406f18 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -1046,26 +1046,24 @@ struct curlFileTransfer : public FileTransfer return ItemHandle(item.get_ptr()); } - ItemHandle - enqueueFileTransfer(const FileTransferRequest & request, Callback callback) noexcept override + inline ref + makeTransferItem(const FileTransferRequest & request, Callback callback) { /* Handle s3:// URIs by converting to HTTPS and optionally adding auth */ if (request.uri.scheme() == "s3") { auto modifiedRequest = request; modifiedRequest.setupForS3(); - auto item = make_ref(*this, std::move(modifiedRequest), std::move(callback)); - try { - return enqueueItem(item); - } catch (const nix::BaseError & e) { - // NOTE(cole-h): catches both nix::Error and nix::Interrupted -- enqueueItem calls - // writeFull which may throw nix::Interrupted, and the rest of enqueueItem may throw - // nix::Error - item->fail(e); - return ItemHandle(item.get_ptr()); - } + return make_ref(*this, std::move(modifiedRequest), std::move(callback)); + } else { + return make_ref(*this, request, std::move(callback)); } + } + + ItemHandle + enqueueFileTransfer(const FileTransferRequest & request, Callback callback) noexcept override + { + const auto item = makeTransferItem(request, std::move(callback)); - auto item = make_ref(*this, request, std::move(callback)); try { return enqueueItem(item); } catch (const nix::BaseError & e) {