libstore/transfer: Warn by default instead of throw for destination changes
Fixes #1004 Change-Id: I2d583fbad40b3c95e37b70167a81c8fb492d5668
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
---
|
||||
synopsis: "Warn instead of erroring when the final destination of a transfer changes in-flight"
|
||||
cls: [4641]
|
||||
issues: [fj#1004]
|
||||
category: "Miscellany"
|
||||
credits: [thubrecht]
|
||||
---
|
||||
|
||||
Lix will now emit a warning during downloads where the final destination changes suddently mid-transfer instead of throwing an error.
|
||||
This transfer behavior has been known to happen very rarely while fetching from some CDNs.
|
||||
@@ -1093,15 +1093,6 @@ struct curlFileTransfer : public FileTransfer
|
||||
co_return result::current_exception();
|
||||
}
|
||||
|
||||
void throwChangedTarget(std::string_view what, std::string_view from, std::string_view to)
|
||||
{
|
||||
if (!from.empty() && from != to) {
|
||||
throw FileTransferError(
|
||||
Misc, {}, "uri %s changed %s from %s to %s during transfer", uri, what, from, to
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
kj::Promise<Result<void>> prepareRetry(
|
||||
const std::string & context,
|
||||
const std::chrono::milliseconds & waitTime,
|
||||
@@ -1135,17 +1126,41 @@ struct curlFileTransfer : public FileTransfer
|
||||
|
||||
kj::Promise<Result<void>> restartTransfer(const std::chrono::milliseconds & timeout)
|
||||
try {
|
||||
auto onChange =
|
||||
[&](std::string_view what, std::string_view from, std::string_view to, bool throw_
|
||||
) -> void {
|
||||
if (!from.empty() && from != to) {
|
||||
FileTransferError e = FileTransferError(
|
||||
Misc,
|
||||
{},
|
||||
"uri %s changed %s from %s to %s during transfer",
|
||||
uri,
|
||||
what,
|
||||
from,
|
||||
to
|
||||
);
|
||||
|
||||
if (throw_) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
logWarning(e.info());
|
||||
}
|
||||
};
|
||||
|
||||
// use the effective URI of the previous transfer for retries. this avoids
|
||||
// some silent corruption if a redirect changes between starting and retry
|
||||
const auto & uri = metadata.effectiveUri.empty() ? this->uri : metadata.effectiveUri;
|
||||
|
||||
auto newMeta = TRY_AWAIT(startTransfer(uri, timeout, totalReceived));
|
||||
throwChangedTarget("final destination", metadata.effectiveUri, newMeta.effectiveUri);
|
||||
throwChangedTarget("ETag", metadata.etag, newMeta.etag);
|
||||
throwChangedTarget(
|
||||
|
||||
onChange("final destination", metadata.effectiveUri, newMeta.effectiveUri, false);
|
||||
onChange("ETag", metadata.etag, newMeta.etag, true);
|
||||
onChange(
|
||||
"immutable url",
|
||||
metadata.immutableUrl.value_or(""),
|
||||
newMeta.immutableUrl.value_or("")
|
||||
newMeta.immutableUrl.value_or(""),
|
||||
true
|
||||
);
|
||||
co_return result::success();
|
||||
} catch (...) {
|
||||
|
||||
Reference in New Issue
Block a user