Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recurring task finished with error [-999] #44

Closed
3 tasks done
rainypixels opened this issue Jul 29, 2020 · 3 comments
Closed
3 tasks done

Recurring task finished with error [-999] #44

rainypixels opened this issue Jul 29, 2020 · 3 comments
Assignees
Labels

Comments

@rainypixels
Copy link

rainypixels commented Jul 29, 2020

Have read the known issues?

  • Yes, I have read and am familiar with the list of known issues.

Have tested on a physical device?

  • Yes, I have tested on physical iOS device and the reported issue is still present.

Does code retain the Connectivity object?

  • Yes, my implementation has a strong reference to the Connectivity object so that it is not deallocated during use.

Describe the bug
I have Connectivity set up with isPollingEnabled set to true. Every 10-20 seconds, I see the following error log in the console:

Task <6FE11EC6-9F9A-486D-8F7B-6A11F4DBAB5D>.<2> finished with error [-999] Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLStringKey=https://captive.apple.com/hotspot-detect.html, NSLocalizedDescription=cancelled, NSErrorFailingURLKey=https://captive.apple.com/hotspot-detect.html}

There are no other side-effects (no crashes, etc.)

To Reproduce
I’m using a pretty trivial implementation of Connectivity in my project. My init method:

private override init() {
  debugPrint("\(type(of: self)) initialized...")
    
  super.init()
    
  let connectivityChanged: Connectivity.NetworkConnected = { [weak self] c in
    self?.updateConnectionStatus(c.status)
  }
    
  networkCheck.isPollingEnabled = true
  networkCheck.framework = .network
    
  networkCheck.whenConnected = connectivityChanged
  networkCheck.whenDisconnected = connectivityChanged
    
  networkCheck.startNotifier()
}

Some notes:

  1. networkCheck is my strongly held reference to Connectivity
  2. updateConnectionStatus merely shows/hides a notice when connectivity on the end device is bad

Expected behavior
I’d expect the error log every once in a while to reflect intermittent connectivity issues. But seeing it reproduce on an interval feels like something’s amiss.

Screenshots
A symbolic breakpoint on write traces its way to Connectivity:

image

Desktop (please complete the following information):

  • OS: macOS Catalina 10.15.6
  • Xcode: 11.6

Smartphone (please complete the following information):

  • Device: iPhone 11
  • OS: iOS 13.5.1

Additional context
I’m using Connectivity 3.3.4 via SPM.

Oh, and thanks for an excellent framework. This is exactly what I needed to replace Reachability and its various wrapper implementations because it handles polling and captive network issues. 💯 ❤️ 👏 🙏

@rwbutler
Copy link
Owner

Hi @rainypixels, I'm aware of this issue - it's not a bug in the sense of something not working, although admittedly it's a bit of a pain getting this message printed to the console.

What's happening here, is that by default the library provides two connectivity endpoints and the default success threshold is set to 50% out of the box. This means that only one connectivity check using a single endpoint needs to succeed in order for the the library to consider the app to have connectivity.

Originally this threshold was set to 75% but it was pointed out to me as part of this issue #41 that in certain countries one of the connectivity endpoints cannot be accessed which means that with a success threshold of 75% and only one working endpoint, in those countries things would fail out of the box.

In order to be performant, the library cancels any connectivity checks that are unnecessary so for example if you provided 10 connectivity endpoints to check and the success threshold was only 50% then after five of the checks complete successfully then the remaining five checks will be cancelled as there is no longer any reason to wait on these to complete if the threshold has already been met.

If you take a look at the Apple documentation here you'll see that -999 is the code used when a network task is cancelled.

I've looked in the past for a way to suppress this message from the logs as it is a nuisance but as it is emitted by URLSession rather than the library itself I haven't found a way to do so presently.

If you're determined to resolve this log message then you could increase the threshold to 75% again which means that the second check will no longer be cancelled (as both checks will need to succeed in order for the success threshold to be met) - this was the original behavior of the library.

Hope this helps 🙂

@rainypixels
Copy link
Author

Ah, that makes perfect sense!

I’m familiar with the -999 error since I’ve had my networking library throw it every once in a while. But I started to wonder if these were unplanned cancellations in the case of Connectivity. I’d even checked out #41 but felt that upping the threshold in prod was a little smelly. That said, now that I think about it, this issue is only slightly annoying during development, so I went ahead and added this to my wrapper (posting for posterity):

var suppressCancellationLogsInDebug: Bool = false {
  didSet {
    #if DEBUG
    networkCheck.successThreshold = suppressCancellationLogsInDebug == true ? .init(75) : .init(50)
    #endif
  }
}

Thanks for the detailed response! 🙌

@rwbutler
Copy link
Owner

rwbutler commented Aug 4, 2020

No problem - glad you found a solution that fits your use case 🙂

@rwbutler rwbutler mentioned this issue Apr 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants