vadymmarkov / Malibu

:surfer: Malibu is a networking library built on promises

Home Page:https://vadymmarkov.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Increased number of errors after updating to 6.3.0+

guilhermearaujo opened this issue · comments

Recently I released two updates of my app with no updates (concerning networking or the requests the app makes, or how and when they are made), but I did update Malibu from 6.2.0 to 6.3.0, and 6.4.0 in the second update.

Since 6.3.0, several customers have been complaining that some contents cannot be load in the app, and send screenshots displaying the error messages I programmed to be displayed when a network request fails for any reason other than 2 cases: Reachability says the device is offline; or the request returns with a 401 status code.

In my tests, I could never reproduce an error, and the worst case I could recreate was to enable the network conditioner with a very poor condition to force a request to time out.

.fail { error in
  switch error {
  case is UnreachableError: Alert.warn(R.string.alert.unreachable()) // Reachability
  case is Unauthorized: AppNotification.loggedOut.post() // 401
  default:
    Alert.warn("some 'could not load' message")
    if !(error is ApiError) { // ApiError is base for UnreachableError, Unauthorized and some other erros like 404, 500, 503, etc.
      Crashlytics.sharedInstance().recordError(error)
    }
  }
}

So I started logging the errors to Crashlytics, but the only data I get from them is:

NSERROR-DOMAIN: Malibu.NetworkError
NSERROR-CODE: 8

Is there any important change since 6.2.0? What case of NetworkError is this one whose code is 8??
How can I debug it better and get more data to understand what's really happening?

This is how the UnreachableError is thrown:

networking.middleware = { promise in
  if let connection = Reachability()?.connection, connection != .none {
    promise.resolve(Void())
  } else {
    promise.reject(UnreachableError())
  }
}

Hey @guilhermearaujo.

I found that "Error Domain=Malibu.NetworkError Code=8" is actually noDataInResponse by doing print(NetworkError.noDataInResponse as NSError).

In the last two released we fixed a couple of issues related to ETags: https://github.com/hyperoslo/Malibu/pull/94 and https://github.com/hyperoslo/Malibu/pull/97. Could it be that you're getting 304 Not Modified for some of your requests? If it so, try to disable Etags functionality if 304 is not supposed to be handled in your app.

Hi @vadymmarkov,
That does seem to be the problem, however it still seems a bit weird:

Prior to #97, the default behaviour for ETag Policy was enabled. This PR changed it to be disabled, and my app does not override it.
Therefore, my app requests (using 6.4.0) should never include the ETag header, I suppose, and consequently, the back-end should not respond with 304.

Is this correct or am I missing a point here?

Update:
I was wrong: the collapsed code made me misinterpret the changes.
GET requests were already supposed to have ETags enabled, and I believed that after these changes they now do work as intended.

Another thing that I haven't understood yet:
Some users reported that the content wouldn't load some times. It kind makes sense if the app gets a 304, but has no cache (or is not using the cache as it should) to complete the promises.

But in my tests, performing the exact same requests, using debug and release builds, I could not reproduce a single error like their reports.

Why isn't if failing consistently? Is it possible that the cache is storing the ETags, but has lost (or corrupted?) the data?

It's hard to say why it isn't failing consistently. You can test ETags by doing the same request multiple times and inspecting the status code. You can also try to clear ETags storage Malibu.clearStorages() to start from the clean state.

Alright then. Things are a bit clearer now, and I sort of know how to investigate it further, I'll close this.