summaryrefslogtreecommitdiff
path: root/apt-private
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2024-11-22 17:59:48 +0000
committerDavid Kalnischkies <david@kalnischkies.de>2024-11-22 20:05:35 +0000
commita732f74400147a9993358b4778335715a0d5e20e (patch)
tree76174389ed4e5a9f61cf8dad20a06ceede8bd8cb /apt-private
parent1a03ebc11982f052259a6b677ebc520f8d47cb81 (diff)
Collect unprinted Ign errors for display in Err output
Instead of deciding if the first or the last error in a retry chain is the best one to display if the entire chain fails in the end we teach our progress reporting to collect the ignored errors (if it hasn't shown them) and print them all together in the Err line. We de-duplicate the collection which makes it harder to match the Ign line with the error messages, but for these cases its probably better to enable direct display of the text anyhow – and repeating the same message multiple times is boring and probably not that helpful for a user wanting to know why all the downloads failed even they asked apt to retry 429 times… References: 841243df877b39dfcb907a7fab9c4e8b4f65d715
Diffstat (limited to 'apt-private')
-rw-r--r--apt-private/acqprogress.cc58
-rw-r--r--apt-private/acqprogress.h3
2 files changed, 44 insertions, 17 deletions
diff --git a/apt-private/acqprogress.cc b/apt-private/acqprogress.cc
index b4b16e6a9..b8b540e75 100644
--- a/apt-private/acqprogress.cc
+++ b/apt-private/acqprogress.cc
@@ -123,39 +123,63 @@ void AcqTextStatus::Fail(pkgAcquire::ItemDesc &Itm)
AssignItemID(Itm);
clearLastLine();
- bool ShowErrorText = true;
+ bool ShowErrorText = false;
if (Itm.Owner->Status == pkgAcquire::Item::StatDone || Itm.Owner->Status == pkgAcquire::Item::StatIdle)
{
// TRANSLATOR: Very short word to be displayed for files in 'apt-get update'
// which failed to download, but the error is ignored (compare "Err:")
ioprintf(out, _("Ign:%lu %s"), Itm.Owner->ID, Itm.Description.c_str());
- if (Itm.Owner->ErrorText.empty() ||
- _config->FindB("Acquire::Progress::Ignore::ShowErrorText", false) == false)
- ShowErrorText = false;
+ if (not Itm.Owner->ErrorText.empty())
+ {
+ if (_config->FindB("Acquire::Progress::Ignore::ShowErrorText", false))
+ ShowErrorText = true;
+ else
+ {
+ if (auto const ignored = IgnoredErrorTexts.find(Itm.Owner->ID); ignored != IgnoredErrorTexts.end())
+ {
+ if (std::find(ignored->second.begin(), ignored->second.end(), Itm.Owner->ErrorText) == ignored->second.end())
+ ignored->second.emplace_back(Itm.Owner->ErrorText);
+ }
+ else
+ IgnoredErrorTexts.emplace(Itm.Owner->ID, std::vector<std::string>{Itm.Owner->ErrorText});
+ }
+ }
}
else
{
// TRANSLATOR: Very short word to be displayed for files in 'apt-get update'
// which failed to download and the error is critical (compare "Ign:")
ioprintf(out, _("Err:%lu %s"), Itm.Owner->ID, Itm.Description.c_str());
+ ShowErrorText = true;
}
- if (ShowErrorText)
+ if (ShowErrorText && not Itm.Owner->ErrorText.empty())
{
- std::string::size_type line_start = 0;
- std::string::size_type line_end;
- while ((line_end = Itm.Owner->ErrorText.find_first_of("\n\r", line_start)) != std::string::npos) {
- out << std::endl << " " << Itm.Owner->ErrorText.substr(line_start, line_end - line_start);
- line_start = Itm.Owner->ErrorText.find_first_not_of("\n\r", line_end + 1);
- if (line_start == std::string::npos)
- break;
+ auto const printErrorText = [](std::ostream &out, std::string_view errortext) {
+ while (not errortext.empty())
+ {
+ auto const line_end = errortext.find_first_of("\n\r");
+ out << "\n " << errortext.substr(0, line_end);
+ if (line_end == std::string_view::npos)
+ break;
+ errortext.remove_prefix(line_end);
+ auto const line_start = errortext.find_first_not_of("\n\r");
+ if (line_start == std::string_view::npos)
+ break;
+ errortext.remove_prefix(line_start);
+ }
+ };
+ if (auto const ignored = IgnoredErrorTexts.find(Itm.Owner->ID); ignored != IgnoredErrorTexts.end())
+ {
+ for (auto const &text : ignored->second)
+ printErrorText(out, text);
+ if (std::find(ignored->second.begin(), ignored->second.end(), Itm.Owner->ErrorText) == ignored->second.end())
+ printErrorText(out, Itm.Owner->ErrorText);
}
- if (line_start == 0)
- out << std::endl << " " << Itm.Owner->ErrorText;
- else if (line_start != std::string::npos)
- out << std::endl << " " << Itm.Owner->ErrorText.substr(line_start);
+ else
+ printErrorText(out, Itm.Owner->ErrorText);
}
- out << std::endl;
+ out << '\n' << std::flush;
Update = true;
}
diff --git a/apt-private/acqprogress.h b/apt-private/acqprogress.h
index 87b957e4b..b4015861c 100644
--- a/apt-private/acqprogress.h
+++ b/apt-private/acqprogress.h
@@ -14,6 +14,8 @@
#include <iostream>
#include <string>
+#include <unordered_map>
+#include <vector>
class APT_PUBLIC AcqTextStatus : public pkgAcquireStatus
{
@@ -22,6 +24,7 @@ class APT_PUBLIC AcqTextStatus : public pkgAcquireStatus
size_t LastLineLength;
unsigned long ID;
unsigned long Quiet;
+ std::unordered_map<unsigned long, std::vector<std::string>> IgnoredErrorTexts;
APT_HIDDEN void clearLastLine();
APT_HIDDEN void AssignItemID(pkgAcquire::ItemDesc &Itm);