Unity web request acting stupid.

Ok, below is the code and the utterly stupid way it’s working.

I send a web request to an API on my server. It’s technically a non-existent php file and it’s handled by a WordPress plugin which responds with a JSON.

If the request.downloadHandler.text response looks like this:

{“status”:“ok”,“Login”:“Valid”,“ViewEula”:true,“SI”:“7036ac55b1a6aa62391cdf1b5ab567c9”}

Everything works as intended. However, if the request.downloadHandler.text looks like this:

{“status”:“error”,“error”:“Invalid username or password.”}

Web request detects that as a request.isHttpError and throws a 404 error:

HTTP/1.1 404 Not Found

I’m having to throw in another check when it detects that 404 to tell it, look if it really is a json response then it’s not a 404 error.

Here’s the code I should be able to use.

    public IEnumerator MyGetRequest(string url, WWWForm formData, Action<bool> callback)
    {
        using (UnityWebRequest request = UnityWebRequest.Post(url, formData))
        {
            // Send the request and wait for a response
            yield return request.SendWebRequest();
            Debug.Log(request.downloadHandler.text);
            if (request.isNetworkError || request.isHttpError)
            {
                Debug.Log(request.error);
                callback(false);
            }
            else
            {
                if (IsValidJson(request.downloadHandler.text))
                {
                    thischeck = FromJSON(request.downloadHandler.text);
                    callback(true);
                }
                else
                {
                    callback(false);
                }
            }
        }
    }

Instead, I’m having to double check to make sure the error it’s detecting really is an error:

    public IEnumerator MyGetRequest(string url, WWWForm formData, Action<bool> callback)
    {
        using (UnityWebRequest request = UnityWebRequest.Post(url, formData))
        {
            // Send the request and wait for a response
            yield return request.SendWebRequest();
            if (request.isNetworkError || request.isHttpError)
            {
                if (!IsValidJson(request.downloadHandler.text))
                {
                    callback(false);
                }
                else
                {
                    thischeck = FromJSON(request.downloadHandler.text);
                    callback(true);
                }
            }
            else
            {
                if (IsValidJson(request.downloadHandler.text))
                {
                    thischeck = FromJSON(request.downloadHandler.text);
                    callback(true);
                }
                else
                {
                    callback(false);
                }
            }
        }
    }

Always get network stuff working outside of Unity in either curl or PostMan, then connect a proxy such as Charles and start trying to replicate the traffic shape with UnityWebRequest.

Any other way risks wasting a lot of your time for trivial issues that only the above way will instantly reveal.

2 Likes

There is no stupid behavior here. isNetworkError tells you that cvomminication with the server has failed, while isHttpError means the server responded with HTTP code that means error (4xx or 5xx).
When you get a network error, the download handler will have no or only partial data, so you can pretty much not validate JSON there.
When you get HTTP error, the download handler contains a server sent message detailing what was the error.

From the example you gave, the server actually sends you a questionable response in the case where you get an error. The 404 generally should be returned when requested thing is not found, there is a different error code for authorization issues, usually 403, see: List of HTTP status codes - Wikipedia

1 Like