BranchMetrics / unity-branch-deep-linking-attribution

The Branch Unity SDK for deep linking and attribution. Branch helps mobile apps grow with deep links / deeplinks that power paid acquisition and re-engagement campaigns, referral programs, content sharing, deep linked emails, smart banners, custom user onboarding, and more.
https://docs.branch.io/apps/unity/
MIT License
118 stars 24 forks source link

KeyNotFoundException on initSession callback on SDK v0.6.7 #197

Open dustinkerstein opened 2 years ago

dustinkerstein commented 2 years ago

Similar to #193, but without ProGuard enabled (using the Branch supplied demo scene) I get this error:

2022-02-27 09:33:25.297 32729-579/? I/Unity: Company Name: DefaultCompany
2022-02-27 09:33:25.297 32729-579/? I/Unity: Product Name: Branch
2022-02-27 09:33:29.712 32729-579/? E/Unity: KeyNotFoundException: The given key was not present in the dictionary.
      at System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key) [0x0001e] in <a1e9f114a6e64f4eacb529fc802ec93d>:0 
      at Branch._asyncCallbackWithParams (System.String callbackDictString) [0x0005f] in <3470cc8ce8154aa898fa31fef48d47fd>:0 
2022-02-27 09:33:29.721 32729-579/? I/Unity: callbackDictString: 

    {"callbackId":"BranchCallbackId1","params":{"universalObject":{},"linkProperties":{}}}
2022-02-27 09:33:29.740 32729-579/? I/Unity: Branch initialization completed: 
2022-02-27 09:33:29.774 32729-579/? I/Unity: Universal Object: {"$canonical_identifier":"","$canonical_url":"","$og_title":"","$og_description":"","$og_image_url":"","$publicly_indexable":"0","$locally_indexable":"0","$exp_date":"69425078400000","$keywords":[],"metadata":"{}"}
2022-02-27 09:33:29.777 32729-579/? I/Unity: Link Properties: {"~tags":[],"~feature":"","~alias":"","~channel":"","~stage":"","~duration":"0","control_params":{}}

It may be benign as I haven't fully tested deep linking yet, but figured I'd post to see if anyone else was seeing this on the current 0.6.7 SDK build. Let me know if you need any further debug.

dustinkerstein commented 2 years ago

Strange, I'm no longer getting this error. Maybe it was something with the Branch API. However, shouldn't these lines (across all of the callback methods) have null protection? Ie:

var callbackId = callbackDict["callbackId"] as string;
var callback = _branchCallbacks[callbackId] as BranchCallbackWithParams;
var callback = _branchCallbacks[callbackId] as BranchCallbackWithStatus;
var callback = _branchCallbacks[callbackId] as BranchCallbackWithList;
var callback = _branchCallbacks[callbackId] as BranchCallbackWithUrl;
var callback = _branchCallbacks[callbackId] as BranchCallbackWithBranchUniversalObject;

->

var callbackId = callbackDict.ContainsKey("callbackId") ? callbackDict["callbackId"] as string : null;
var callback = _branchCallbacks.ContainsKey(callbackId) ? _branchCallbacks[callbackId] as BranchCallbackWithParams : null;
var callback = _branchCallbacks.ContainsKey(callbackId) ? _branchCallbacks[callbackId] as BranchCallbackWithStatus : null;
var callback = _branchCallbacks.ContainsKey(callbackId) ? _branchCallbacks[callbackId] as BranchCallbackWithList : null;
var callback = _branchCallbacks.ContainsKey(callbackId) ? _branchCallbacks[callbackId] as BranchCallbackWithUrl : null;
var callback = _branchCallbacks.ContainsKey(callbackId) ? _branchCallbacks[callbackId] as BranchCallbackWithBranchUniversalObject : null;
dustinkerstein commented 2 years ago
diff --git a/Assets/Branch/Branch.cs b/Assets/Branch/Branch.cs
index 6e1e3f90..48e4c6f4 100644
--- a/Assets/Branch/Branch.cs
+++ b/Assets/Branch/Branch.cs
@@ -854,11 +854,11 @@ public class Branch : MonoBehaviour {

     public void _asyncCallbackWithParams(string callbackDictString) {
                var callbackDict = BranchThirdParty_MiniJSON.Json.Deserialize(callbackDictString) as Dictionary<string, object>;
-        var callbackId = callbackDict["callbackId"] as string;
+        var callbackId = callbackDict.ContainsKey("callbackId") ? callbackDict["callbackId"] as string : null;
         Dictionary<string, object> parameters = callbackDict.ContainsKey("params") ? callbackDict["params"] as Dictionary<string, object> : null;
         string error = callbackDict.ContainsKey("error") ? callbackDict["error"] as string : null;

-               var callback = _branchCallbacks[callbackId] as BranchCallbackWithParams;
+               var callback = _branchCallbacks.ContainsKey(callbackId) ? _branchCallbacks[callbackId] as BranchCallbackWithParams : null;
                if (callback != null) {
                        callback(parameters, error);
                }
@@ -866,11 +866,11 @@ public class Branch : MonoBehaviour {

     public void _asyncCallbackWithStatus(string callbackDictString) {
                var callbackDict = BranchThirdParty_MiniJSON.Json.Deserialize(callbackDictString) as Dictionary<string, object>;
-        var callbackId = callbackDict["callbackId"] as string;
+        var callbackId = callbackDict.ContainsKey("callbackId") ? callbackDict["callbackId"] as string : null;
         bool status = callbackDict.ContainsKey("status") ? (callbackDict["status"] as bool?).Value : false;
         string error = callbackDict.ContainsKey("error") ? callbackDict["error"] as string : null;

-        var callback = _branchCallbacks[callbackId] as BranchCallbackWithStatus;
+        var callback = _branchCallbacks.ContainsKey(callbackId) ? _branchCallbacks[callbackId] as BranchCallbackWithStatus : null;
                if (callback != null) {
                callback(status, error);
                }
@@ -878,11 +878,11 @@ public class Branch : MonoBehaviour {

     public void _asyncCallbackWithList(string callbackDictString) {
                var callbackDict = BranchThirdParty_MiniJSON.Json.Deserialize(callbackDictString) as Dictionary<string, object>;
-        var callbackId = callbackDict["callbackId"] as string;
+        var callbackId = callbackDict.ContainsKey("callbackId") ? callbackDict["callbackId"] as string : null;
                List<object> list = callbackDict.ContainsKey("list") ? callbackDict["list"] as List<object> : null;
         string error = callbackDict.ContainsKey("error") ? callbackDict["error"] as string : null;

-        var callback = _branchCallbacks[callbackId] as BranchCallbackWithList;
+        var callback = _branchCallbacks.ContainsKey(callbackId) ? _branchCallbacks[callbackId] as BranchCallbackWithList : null;
                if (callback != null) {
                callback(list, error);
                }
@@ -890,11 +890,11 @@ public class Branch : MonoBehaviour {

     public void _asyncCallbackWithUrl(string callbackDictString) {
                var callbackDict = BranchThirdParty_MiniJSON.Json.Deserialize(callbackDictString) as Dictionary<string, object>;
-        var callbackId = callbackDict["callbackId"] as string;
+        var callbackId = callbackDict.ContainsKey("callbackId") ? callbackDict["callbackId"] as string : null;
         string url = callbackDict.ContainsKey("url") ? callbackDict["url"] as string : null;
         string error = callbackDict.ContainsKey("error") ? callbackDict["error"] as string : null;
klim-branch commented 2 years ago

Hey,

When you were testing this, can I have a bit more information on this? Especially whether you have configured your key (branch key) for the Branch object?

dustinkerstein commented 2 years ago

I was testing this on 2/27 around 9-10am PT. And yes, I had my Branch (live) key configured. Is there anything else I can get you?

klim-branch commented 2 years ago

Interesting... today I had chance to reproduce this test case, but no luck. By any chance, do you have version of git where it can reproduce this issue? Or perhaps very detailed descriptions of the time when you saw that message would be very appreciated 🙏

dustinkerstein commented 2 years ago

Unfortunately the best I have is from the timestamp above: 2022-02-27 09:33:29.712 which is GMT -08:00

Let me know if there's anything else I can help with, and if you can't replicate still, feel free to close this issue. Though maybe it is a good idea to have null checks as noted above. I'll leave that up to you.

klim-branch commented 2 years ago

Thanks, @dustinkerstein For the suggestion. Let me give it a try for a week, and search if there was a similar case on the other SDKs. @echo-branch Hey, could you please advise me where to look at it?

popisdead commented 2 years ago

bump, we are keeping on having this error for a year. Is benign (things work) but annoying. KeyNotFoundException: The given key was not present in the dictionary. at System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key)

klim-branch commented 2 years ago

Hey @popisdead I was finally able to reproduce the problem as well while developing my game last night. It seems like there is no pattern with this error, just randomly coming up. It definitely looks like a bug. Let me raise an internal ticket regarding to it to further investigate on it.

popisdead commented 2 years ago

terrific @klim-branch! Do you have an ETA to release a fix? Happy to help by coding (need hints, however) or debugging if you need some help.