EC: aggregate per-link result into a single ADD_LINK response - #551
Merged
mrjimenez merged 1 commit intoMay 11, 2026
Merged
Conversation
EC_OP_ADD_LINK iterated over the request's link tags and built a fresh response on every loop iteration, deleting the previous one. The last link's outcome decided what the caller saw -- so a batch of N-1 successes followed by one failure looked like total failure to the client, and the converse case (N-1 failures + 1 success) looked like total success. Count successes and failures across the loop and emit one response at the end: - all succeed -> EC_OP_NOOP (unchanged) - all fail -> EC_OP_FAILED + 'Invalid link...' (unchanged) - mixed (any failure) -> EC_OP_FAILED + 'X of N links failed...' The new partial-failure string is added to the i18n catalog via wxTRANSLATE, matching the existing pattern at lines 811 / 904. Per-link error reasons are still printed locally by AddLink(), so the daemon log keeps the full diagnostic. Closes amule-project#206
This was referenced May 9, 2026
mrjimenez
pushed a commit
that referenced
this pull request
May 11, 2026
CDownQueueRem::AddLink() used to drop the EC reply on the floor:
m_conn->SendPacket(&req); // fire-and-forget, no handler
So when amuled rejected a link with EC_OP_FAILED + an
EC_TAG_STRING explaining the reason ('Invalid link or already on
list.' / 'Unknown protocol of link: ...'), amulegui silently
swallowed the failure -- the link didn't get added but no error
appeared in the UI. Verified during #310 retest: pasting the
original reproducer 'ed2k::3D366ED505B977FC61C9A6EE01E96329'
makes amuled log 'Unknown protocol of link: ...' and return the
failure packet, but amulegui shows nothing to the user.
Add CAddLinkHandler (matching the existing CCatHandler shape used
for EC_OP_CREATE_CATEGORY failures) and switch AddLink() to
SendRequest() so the reply is dispatched to it. On EC_OP_FAILED
we wxMessageBox the daemon's translated error string; the
fallback path reuses the same primary string ('Invalid link or
already on list.') which is already in po/amule.pot at line 1783,
so no new translation strings need adding to the catalog.
Each amulegui AddLink() call sends one EC packet with a single
link tag, so each failed link gets its own dialog (the textbox
add-loop in amuleDlg.cpp:958 calls AddLink() per non-empty line).
The aggregate-message path in PR #551 ("%d of %d links failed")
fires when the caller bundles multiple link tags into one packet
-- amulecmd does that today, amulegui does not. Batching amulegui
sends would be a separate UX change; for now each per-link failure
shows its own dialog, which is still strictly better than the
previous silent-drop.
Verified end-to-end: built aMuleGUI.app on macOS, connected to
amuled on the Linux dev VM, pasted the malformed link -- error
dialog appears with 'Invalid link or already on list.'. Mixed
batch (1 valid + 1 invalid) gets one dialog for the invalid
link and adds the valid one silently, matching the per-link
contract.
Follow-up to #310. Closes the silent-failure ergonomic gap that
surfaced during the #310 fixed-by-baseline verification.
got3nks
added a commit
to got3nks/amule
that referenced
this pull request
May 11, 2026
…ct#310) Adds a batch CDownloadQueue::AddLinks / CDownQueueRem::AddLinks abstraction and routes the GUI's batch callers (Fast eD2k paste box, .emulecollection import) through it. Centralises the popup aggregation logic and fixes both monolithic *and* amulegui in one move. Background: PR amule-project#557 made amulegui's CAddLinkHandler pop a wxMessageBox so an EC_OP_FAILED reply from EC_OP_ADD_LINK surfaces to the user instead of being silently dropped (amule-project#310). The same regression existed in the monolithic amule binary: CDownloadQueue::AddLink logs the failure via AddLogLineC and returns false, but no UI feedback ever reaches the user. The naive fix -- popping a wxMessageBox inside AddLink -- produces N dialogs when the user pastes N invalid lines into the Fast eD2k box. PR amule-project#551 had already taught amuled's EC handler to accept N tags in one EC_OP_ADD_LINK packet and emit a single aggregated EC_OP_FAILED response, but amulegui's CDownQueueRem::AddLink was still looping client-side and sending one packet per link, so CAddLinkHandler still fired once per failure. Change: 1. CDownloadQueue::AddLinks(wxArrayString, cat) Calls AddLink in a loop, counts failures, dispatches a single wxPLURAL'd ShowAlert at the end. ShowAlert is polymorphic (wxMessageBox under amule, log-only under amuled), so the same code is safe to compile into the daemon. 2. CDownQueueRem::AddLinks(wxArrayString, cat) Packs the entire batch into one EC_OP_ADD_LINK packet (one child tag per link, EC_TAG_PARTFILE_CAT carrying the category). Daemon aggregates per PR amule-project#551; CAddLinkHandler fires exactly once with the existing catalog string ("%d of %d links failed..."). 3. The two uniform-cat batch callers now call AddLinks instead of looping AddLink: - CamuleDlg::OnBnClickedFast (Fast eD2k paste box) - CSharedFilesCtrl::OnAddCollection (.emulecollection import) 4. CamuleAppCommon::AddLinksFromFile (ED2KLinks-in-config-dir poller) keeps its own per-line counter + AddLink-in-loop because each line may carry its own ":CAT" suffix, which doesn't fit the single-cat AddLinks signature. Rare path, rare feature -- left alone. CDownloadQueue::AddLink itself is untouched; it still logs the protocol-specific reason per failure, which the aggregated popup intentionally points to ("see log for details") rather than duplicating inline.
mrjimenez
pushed a commit
that referenced
this pull request
May 11, 2026
Adds a batch CDownloadQueue::AddLinks / CDownQueueRem::AddLinks abstraction and routes the GUI's batch callers (Fast eD2k paste box, .emulecollection import) through it. Centralises the popup aggregation logic and fixes both monolithic *and* amulegui in one move. Background: PR #557 made amulegui's CAddLinkHandler pop a wxMessageBox so an EC_OP_FAILED reply from EC_OP_ADD_LINK surfaces to the user instead of being silently dropped (#310). The same regression existed in the monolithic amule binary: CDownloadQueue::AddLink logs the failure via AddLogLineC and returns false, but no UI feedback ever reaches the user. The naive fix -- popping a wxMessageBox inside AddLink -- produces N dialogs when the user pastes N invalid lines into the Fast eD2k box. PR #551 had already taught amuled's EC handler to accept N tags in one EC_OP_ADD_LINK packet and emit a single aggregated EC_OP_FAILED response, but amulegui's CDownQueueRem::AddLink was still looping client-side and sending one packet per link, so CAddLinkHandler still fired once per failure. Change: 1. CDownloadQueue::AddLinks(wxArrayString, cat) Calls AddLink in a loop, counts failures, dispatches a single wxPLURAL'd ShowAlert at the end. ShowAlert is polymorphic (wxMessageBox under amule, log-only under amuled), so the same code is safe to compile into the daemon. 2. CDownQueueRem::AddLinks(wxArrayString, cat) Packs the entire batch into one EC_OP_ADD_LINK packet (one child tag per link, EC_TAG_PARTFILE_CAT carrying the category). Daemon aggregates per PR #551; CAddLinkHandler fires exactly once with the existing catalog string ("%d of %d links failed..."). 3. The two uniform-cat batch callers now call AddLinks instead of looping AddLink: - CamuleDlg::OnBnClickedFast (Fast eD2k paste box) - CSharedFilesCtrl::OnAddCollection (.emulecollection import) 4. CamuleAppCommon::AddLinksFromFile (ED2KLinks-in-config-dir poller) keeps its own per-line counter + AddLink-in-loop because each line may carry its own ":CAT" suffix, which doesn't fit the single-cat AddLinks signature. Rare path, rare feature -- left alone. CDownloadQueue::AddLink itself is untouched; it still logs the protocol-specific reason per failure, which the aggregated popup intentionally points to ("see log for details") rather than duplicating inline.
got3nks
added a commit
to got3nks/amule
that referenced
this pull request
Jul 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #206 (originally reported by @gonosztopi). The
EC_OP_ADD_LINKhandler iterated over the request's link tags and built a fresh response on every loop iteration, deleting the previous one. The last link's outcome therefore decided what the caller saw — a batch of N-1 successes followed by one failure looked like total failure to the client, and the converse case (N-1 failures + 1 success) looked like total success.Fix
Count successes and failures across the loop and emit one response at the end:
EC_OP_NOOP(unchanged)EC_OP_FAILED+Invalid link or already on list.(unchanged)EC_OP_FAILED+X of N links failed (invalid or already on list).The new partial-failure string goes through
wxTRANSLATEso the i18n catalog picks it up, matching the existingCFormat(wxString(wxTRANSLATE(...)))pattern used at lines 811 and 904 of the same file. Per-link error reasons are still printed locally byAddLink(), so the daemon log keeps the full diagnostic.Verification
Built
src/ExternalConn.cppclean on Ubuntu 26.04 ARM64, libwx 3.2.Closes #206