Skip to content

amule-remote-gui: surface EC_OP_FAILED from EC_OP_ADD_LINK to the user - #557

Merged
mrjimenez merged 1 commit into
amule-project:masterfrom
got3nks:fix/amulegui-add-link-error-feedback
May 11, 2026
Merged

amule-remote-gui: surface EC_OP_FAILED from EC_OP_ADD_LINK to the user#557
mrjimenez merged 1 commit into
amule-project:masterfrom
got3nks:fix/amulegui-add-link-error-feedback

Conversation

@got3nks

@got3nks got3nks commented May 9, 2026

Copy link
Copy Markdown
Contributor

Summary

CDownQueueRem::AddLink() was fire-and-forget — it sent the EC_OP_ADD_LINK packet and ignored the reply. 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.

Surfaced during #310 verification: with the original reproducer ed2k::3D366ED505B977FC61C9A6EE01E96329, amuled logs Unknown protocol of link: ... and returns the failure packet, but amuleGUI showed nothing to the user.

Fix

Add CAddLinkHandler (matching the existing CCatHandler pattern 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 (no string tag — defensive only, daemon always tags) reuses the same primary string Invalid link or already on list. which is already in po/amule.pot:1783, so no new translation strings need adding to the catalog.

Per-link vs batched

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 #551 (%d of %d links failed) fires when the caller bundles multiple link tags into one packet — amulecmd does that today, amuleGUI doesn't. Batching amuleGUI's sends is a separate UX change; for now each per-link failure shows its own dialog, which is strictly better than the previous silent-drop.

Verification

End-to-end on master + #551: built aMuleGUI.app on macOS, connected to amuled on the Linux dev VM:

Test case Result
Single valid link Added, no dialog ✓
Single invalid link (ed2k::3D366ED505B977FC61C9A6EE01E96329) Dialog: "Invalid link or already on list." ✓
Mixed batch (1 valid + 1 invalid) Valid one added, dialog for invalid one ✓

Follow-up to #310 (the original assertion-crash bug, fixed-by-baseline since 2.3.3 era). Closes the silent-failure ergonomic gap that surfaced during the #310 verification.

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 amule-project#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 amule-project#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 amule-project#310. Closes the silent-failure ergonomic gap that
surfaced during the amule-project#310 fixed-by-baseline verification.
@mrjimenez
mrjimenez merged commit 807e8eb into amule-project:master May 11, 2026
12 checks passed
@got3nks
got3nks deleted the fix/amulegui-add-link-error-feedback branch May 11, 2026 08:00
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 23, 2026
…er (amule-project#557)

Follow-up to amule-project#554. Jwt.cpp and Api.cpp each carried an identical include block -- a PICOJSON_USE_INT64 define plus the #ifdef AMULE_PICOJSON_HEADER selection. Since PICOJSON_USE_INT64 changes the layout of picojson::value, the two use sites drifting apart would be an ODR violation the compiler cannot catch.

Move both to src/libwebcommon/PicoJson_Inc.h, a single guarded include site, mirroring the existing CryptoPP_Inc.h wrapper. Both TUs now include "PicoJson_Inc.h", so the int64 toggle and the bundled/system header selection have one source of truth. No behaviour change; verified with clean bundled and system builds, JwtTest passing in both.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants