customerio / customerio-ios

Official Customer.io SDK for iOS. Track customers and send messages to your iOS app.
https://customer.io/docs/sdk/ios/
MIT License
27 stars 16 forks source link

Error logs #134

Closed benjamincombes closed 2 years ago

benjamincombes commented 2 years ago

Hi, I just integrated the SDK, and have many of the following errors:

 [CIO] 🛑 4xx HTTP status code response.
Probably a bug? Response received, but status code = 400. event data must be a hash

Any clue on what causes this and how to fix it?

hownowstephen commented 2 years ago

Happy to help! Sounds like the data being passed in your event body isn't being serialized at the top level to a key/value pair. Anything you pass to the data parameter of the track function should be serializable to a JSON map/hash at the top level.

It looks like our implementation of Encodable makes it possible to pass in something that doesn't serialize to a hash-like object. I'll raise an issue internally to improve validation of the data, but in the meantime I recommend you ensure that whatever you're passing through will be serialized to a JSON hash object at the top level. For further details, click here for the API documentation for our track endpoint

If you continue to run into this error response after checking that your data should serialize properly, let us know & we're happy to help dig in further - if that is the case, some sample code showing how you've integrated would be very helpful in letting us reproduce the behaviour on our end.

benjamincombes commented 2 years ago

Yes, that's what I thought, but it looks a bit weird, as it compiles fine, so there should be no particular problems here. Moreover, I track on multiple services (Mixpanel / Firebase...), and the same data works fine for them, while they have similar data types limitations. The other weird thing is that all tracking seem to appear on the Customer.io website's activity logs, with data present too. Here is an example of some data I can send :

name: "pusher.availability_did_change"
data: {"connexion_available":"true","channel_available":"false","available":"false"}}

Do you see something that should not work? And here is the internal type I use for trackers data (that is optional):

public typealias Properties = [String: String]

If it can help too, the error seems to appear multiple times for each call: in an example session, I tracked 26 events; I got 76 times the message:

[CIO] 🛑 4xx HTTP status code response.
Probably a bug? Response received, but status code = 400. event data must be a hash
levibostian commented 2 years ago

Hello @benjamincombes 👋. Thanks for sending us some more information.

In regards to your comment about how the error seems to appear multiple times for each call, the Customer.io SDK uses a background queue to perform all HTTP requests. So, when you, for example, call CustomerIO.shared.track(), 1 task gets added to the background queue. The queue will continue to retry the HTTP request until it is successful. Because the HTTP request resulted in a 400, the queue will retry the HTTP request. This is my guess as to why you see the error 76 times.

This would be easier to debug for you if we knew what HTTP request was resulting in this 400. If you could, please, enable debug logging of the SDK and run your app until you see the 400 error happen.

Then, email us SDK logs to win@customer.io. In the email, reference this GitHub issue and mention Levi asked you for the logs.

The SDK logs will tell us what HTTP request is happening with what request data. That should help us to reproduce this issue and then get it fixed for you!

benjamincombes commented 2 years ago

Hi @levibostian, I just sent the email, let me know if this is enough for you!

levibostian commented 2 years ago

I think I was able to reproduce your error.

In your app source code, are you calling the SDK CustomerIO.track() function with nil as the data parameter?

Here is an example of sending nil:

struct Foo: Encobable {}

let data: Foo? = nil
customerIO.track(name: "", data: data)

There are multiple versions of the track() function. 1 of them does allow nil. There is a bug with this function. nil gets send in the HTTP request when it shouldn't.

Assuming you are setting data = nil...

To temporarily fix the 400 issue in your app, for the places in your code where you are calling track() with data parameter nil, instead call the track() function without a data parameter at all: CustomerIO.track(name: "").

I hope this isn't a lot of work on your end to do. I will get this fixed for you so you can go back to using data = nil.

levibostian commented 2 years ago

Bug fixed with PR: https://github.com/customerio/customerio-ios/pull/135

levibostian commented 2 years ago

@benjamincombes SDK version 1.0.1 has been released with the bug fix.

benjamincombes commented 2 years ago

@levibostian thanks a lot, I'll update it right now!

benjamincombes commented 2 years ago

Hi @levibostian it looks like I have the same problem... I just sent you new logs, let me know if you need anything else!

levibostian commented 2 years ago

Thank you. I replied to your ticket @benjamincombes

levibostian commented 2 years ago

I was able to reproduce the issue you're experiencing, @benjamincombes. A bug fix has been created and submitted. I'll publish 1.0.2 once the PR status checks all pass.

levibostian commented 2 years ago

1.0.2 has been deployed.

benjamincombes commented 2 years ago

Great, thanks @levibostian it looks like it works now!