4

I have a Unity game hosted on a web publishing platform. This game connects to several APIs, including Microsoft PlayFab, Google Analytics, and our own back end server. Sometimes (very rarely, less than 0.1% of the time) the game fails to connect to any of these services, and I'm not sure why. I have never been able to reproduce this locally. We currently have not been able to isolate it to a particular region, due to its rarity. It seems to affect specific computers/households. Multiple browsers on the same computer running the game will fail the same way. Sometimes multiple computers in the same household will also be affected.

Microsoft and Google both return a 400 error, and our own service replies with a 400. Unity notes that an 'Unknown Error' occurred during the UnityWebRequest.

I cannot look at the data sent/received with Microsoft or Google, but I can look at our own server logs, and things get strange. The UnityWebRequest is making it to our service, which is hosted on AWS and proxied by CloudFlare. The URL is correct, but the request body seems completely bizarre:

"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\b\u0000\u0000\u0000\u0000\u0000\u0000\u0000xך\u0000\u0000\u0000\u0000\u0000`ך\u0000�\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000`ך\u0000!\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"

That's the contents of the request body. If I grab the bytes (assuming a UTF8 encoded string) then I get the following:

byte[72] { 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 120, 215, 154, 0, 0, 0, 0, 0, 96, 215, 154, 0, 239, 191, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 215, 154, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }

My first guess was that AWS/CloudFlare/Google are perhaps blocked by certain firewalls or regions, but if that were the case I would not expect anything to have made it to our own AWS server to analyze. So now I am not sure...

Here's the relevant Unity (2018.2.21f1) code:

UnityWebRequest www = UnityWebRequest.Post(uri, body);
UploadHandlerRaw uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(body));
uploadHandler.contentType = "application/json";
www.uploadHandler = uploadHandler;
www.SetRequestHeader("Content-Type", "application/json");

yield return www.Send();

if (www.isNetworkError || www.isHttpError)
{
    Log(ELoggingLevel.Error, "Error while sending data: [{0}]", www.error);
}
else
{
    var contents = www.downloadHandler.text;
    // do useful stuff here
}

The logger does fire, so either isNetworkError or isHttpError are true.

[Error]: Error while sending data: [Unknown Error]

Does anyone have any thoughts on what is going on? Does anyone recognize that data being logged by the server? It appears like my Unity game just refuses to send any type of reasonable data in some sort of rare situation.

Edit: I logged the content type on the server, and am correctly getting application/json, which would suggest a solid amount of the data is arriving properly. The body data is also identical across multiple users. Unity is probably only returning an error because of the 400 being returned by the server.

Giawa
  • 1,281
  • 1
  • 10
  • 21

2 Answers2

2

I have struggled with the exact same error. Clients using my app received a 400 or Unknown Error rarely. Locally I could not reproduce this. However it was not with an upload, but with several (different) post requests. I use a different server provider as you do though.

I tried looking for a reason (and answer) but could never find one.

I did manage to create a workaround/ solution for it though. It seems that if you execute the same action 0.1 second later, it would pass without problem. So I suggest implementing something like the following.

int tryCounts = 3;

for (int i = 0; i < tryCounts; i++)
{
    UnityWebRequest www = UnityWebRequest.Post(uri, body);
    UploadHandlerRaw uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(body));
    uploadHandler.contentType = "application/json";
    www.uploadHandler = uploadHandler;
    www.SetRequestHeader("Content-Type", "application/json");

    yield return www.Send();

    if (www.isNetworkError || www.isHttpError)
    {
        Log(ELoggingLevel.Error, "Error while sending data: [{0}]", www.error);
        yield return new WaitForSecondsRealtime(0.15f); 
    }
    else
    {
        var contents = www.downloadHandler.text;
        // do useful stuff here
        break;
    }
}

This simple solution fixed all my problems. I still see an unknown error pop in my database errorlog from time to time. Since I also log the trycount, I can confirm that I never had it pop up twice in a row.

Immorality
  • 2,164
  • 2
  • 12
  • 24
  • Very interesting! Mine is a POST request as well. Does this only affect your webgl copies of the game, or are standalone builds affected as well (assuming you are also using Unity)? I'll give this a try and report back. Thanks – Giawa Dec 05 '19 at 15:35
  • Oh i'm sorry, I meant mine does not use an upload handler. I do not have webgl copies, i have android/ ios builds using Unity. I'm pretty sure it is related to UnityWebRequest, but can't find any official sources on this. – Immorality Dec 05 '19 at 15:52
  • We ended up finding the source of the issue, so it sounds like we may be suffering from different problems. Glad to hear your solution works for you, and thanks for checking out this question :) – Giawa Dec 06 '19 at 01:03
  • It does indeed sound like something different then. Glad to hear that you managed to resolve it – Immorality Dec 06 '19 at 07:51
1

This particular issue was caused by antivirus software. We found the affected users were using Kaspersky antivirus, and specifically a feature called 'Integrate script for interaction with websites into traffic', under the 'Traffic Processing' tab. I have no clue why Kaspersky thinks this is a reasonable thing to do, and I imagine it must break more than just our game, but there it is. The user can simply disable that option in Kaspersky and the UnityWebRequest will run as normal.

Giawa
  • 1,281
  • 1
  • 10
  • 21