beeradmoore/dlss-swapper · error · Exception

Could not download file.

Error message

Could not download file.

What it means

DLLRecord.DownloadAsync throws this when FileDownloader.DownloadFileToStreamAsync completes but reports didDownload == false, i.e. the HTTP transfer did not succeed (non-success status, empty body, or the downloader's failure condition) yet no exception was raised by the downloader itself. The library refuses to continue to zip validation/extraction with a file it did not actually download.

Solutions

  1. Check the package URL in the manifest is still valid (open it in a browser/curl)
  2. Retry the download after verifying network/proxy access
  3. Update the app/manifest to pick up corrected asset URLs
  4. Inspect FileDownloader behavior/status codes for why it returned false and surface the HTTP status

Example fix

// before
var didDownload = await LocalRecord.FileDownloader.DownloadFileToStreamAsync(fileStream, cancellationToken).ConfigureAwait(false);
if (didDownload == false)
{
    throw new Exception("Could not download file.");
}
// after
var didDownload = await LocalRecord.FileDownloader.DownloadFileToStreamAsync(fileStream, cancellationToken).ConfigureAwait(false);
if (didDownload == false)
{
    throw new Exception($"Could not download file from {DownloadUrl}.");
}
Defensive patterns

Strategy: retry

Validate before calling

// preflight the URL before DownloadAsync
using var resp = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, downloadUrl));
if (!resp.IsSuccessStatusCode)
    throw new HttpRequestException($"Asset URL {downloadUrl} returned {(int)resp.StatusCode}.");

Try / catch

try
{
    await dllRecord.DownloadAsync();
}
catch (Exception ex) when (ex.Message == "Could not download file.")
{
    await Task.Delay(TimeSpan.FromSeconds(5));
    await dllRecord.DownloadAsync(); // one retry before surfacing to user
}

Prevention

When it happens

Trigger: Calling DownloadAsync (directly or via update/install flows) when the remote zip URL returns a non-success status the downloader tolerates, a redirect to an error page it treats as no-content, or the network drops such that the downloader returns false instead of throwing.

Common situations: CDN returning 403/404 handled as 'false' by FileDownloader; expired or moved GitHub release asset URL; firewall/proxy blocking the download host; rate limiting on the download endpoint.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of beeradmoore/dlss-swapper@ab9b1e2d4b (2026-09-15). Data as JSON: /api/errors/9a1ecb8da78ff3e6. Report an issue: GitHub.

Appendix: source

Thrown at src/Data/DLLRecord.cs:295

        _cancellationTokenSource = new CancellationTokenSource();
        var cancellationToken = _cancellationTokenSource.Token;

        var fileDownloader = new FileDownloader(DownloadUrl);
        var tempZipFile = Path.Combine(Storage.GetTemp(), $"{fileDownloader.Guid.ToString("D").ToUpper()}.zip");

        try
        {
            LocalRecord.FileDownloader = fileDownloader;
            NotifyPropertyChanged(nameof(LocalRecord));


            using (var fileStream = new FileStream(tempZipFile, FileMode.Create, FileAccess.ReadWrite, FileShare.None, FileDownloader.BufferSize, true))
            {
                var didDownload = await LocalRecord.FileDownloader.DownloadFileToStreamAsync(fileStream, cancellationToken).ConfigureAwait(false);

                if (didDownload == false)
                {
                    throw new Exception("Could not download file.");
                }

                if (ZipMD5Hash != fileStream.GetMD5Hash())
                {
                    throw new Exception("Downloaded file was invalid.");
                }

                fileStream.Position = 0;

                using (var zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Read, true))
                {
                    DLLManager.HandleExtractFromZip(zipArchive, this);
                }
            }

            App.CurrentApp.RunOnUIThread(() =>
            {
                LocalRecord.IsDownloaded = true;

View on GitHub (pinned to ab9b1e2d4b)