Commit 561c44687f

561c44687fc1c9d596025730e04a62bc9913a2e3

parent: 0aff03c96c

Unsigned

cmc <hello@cleberg.net> · 2026-04-13 22:41 UTC

fix: suppress false "network request failed" error on ticket list scroll

When scrolling through a large tracker, SwiftUI's .task modifier cancels
in-flight pagination requests as rows leave the screen. URLSession
responds with URLError(-999), which was being surfaced to the user as
"The network request failed. Please try again." — even though the
cancellation is expected and benign.

Guard against Task.isCancelled in the catch block so cancellations are
silently ignored; isLoadingMore is still reset unconditionally so the
next scroll attempt retries from the same cursor position.

Fixes: https://todo.sr.ht/~ccleberg/hutch/61

Layout: unified · split

Hutch.xcodeproj/project.pbxproj +6 −6
@@ -515,7 +515,7 @@
515515 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
516516 CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements;
517517 CODE_SIGN_STYLE = Automatic;
518 CURRENT_PROJECT_VERSION = 66;
518 CURRENT_PROJECT_VERSION = 67;
519519 DEVELOPMENT_TEAM = ZCNAX3VL9D;
520520 ENABLE_PREVIEWS = YES;
521521 GENERATE_INFOPLIST_FILE = YES;
@@ -532,7 +532,7 @@
532532 "$(inherited)",
533533 "@executable_path/Frameworks",
534534 );
535 MARKETING_VERSION = 3.0.5;
535 MARKETING_VERSION = 3.0.6;
536536 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch;
537537 PRODUCT_NAME = "$(TARGET_NAME)";
538538 STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -552,7 +552,7 @@
552552 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
553553 CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements;
554554 CODE_SIGN_STYLE = Automatic;
555 CURRENT_PROJECT_VERSION = 66;
555 CURRENT_PROJECT_VERSION = 67;
556556 DEVELOPMENT_TEAM = ZCNAX3VL9D;
557557 ENABLE_PREVIEWS = YES;
558558 GENERATE_INFOPLIST_FILE = YES;
@@ -569,7 +569,7 @@
569569 "$(inherited)",
570570 "@executable_path/Frameworks",
571571 );
572 MARKETING_VERSION = 3.0.5;
572 MARKETING_VERSION = 3.0.6;
573573 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch;
574574 PRODUCT_NAME = "$(TARGET_NAME)";
575575 STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -642,7 +642,7 @@
642642 "@executable_path/Frameworks",
643643 "@executable_path/../../Frameworks",
644644 );
645 MARKETING_VERSION = 3.0.5;
645 MARKETING_VERSION = 3.0.6;
646646 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension;
647647 PRODUCT_NAME = "$(TARGET_NAME)";
648648 SKIP_INSTALL = YES;
@@ -671,7 +671,7 @@
671671 "@executable_path/Frameworks",
672672 "@executable_path/../../Frameworks",
673673 );
674 MARKETING_VERSION = 3.0.5;
674 MARKETING_VERSION = 3.0.6;
675675 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension;
676676 PRODUCT_NAME = "$(TARGET_NAME)";
677677 SKIP_INSTALL = YES;
Hutch/Views/Tickets/TicketListViewModel.swift +5 −1
@@ -341,7 +341,11 @@ final class TicketListViewModel {
341341 hasMore = page.cursor != nil
342342 reconcileSelectionWithLoadedTickets()
343343 } catch {
344 self.error = error.userFacingMessage
344 // Ignore cancellation errors — the SwiftUI .task modifier cancels in-flight
345 // requests when a row scrolls off-screen, which is expected behavior.
346 if !Task.isCancelled {
347 self.error = error.userFacingMessage
348 }
345349 }
346350
347351 isLoadingMore = false