private void HandleResponse()

in Scripts/Runtime/WitRequest.cs [466:617]


        private void HandleResponse(IAsyncResult ar)
        {
            string stringResponse = "";
            responseStarted = true;
            try
            {
                response = (HttpWebResponse) _request.EndGetResponse(ar);

                statusCode = (int) response.StatusCode;
                statusDescription = response.StatusDescription;

                try
                {
                    var responseStream = response.GetResponseStream();
                    if (response.Headers["Transfer-Encoding"] == "chunked")
                    {
                        byte[] buffer = new byte[10240];
                        int bytes = 0;
                        int offset = 0;
                        int totalRead = 0;
                        while ((bytes = responseStream.Read(buffer, offset, buffer.Length - offset)) > 0)
                        {
                            totalRead += bytes;
                            stringResponse = Encoding.UTF8.GetString(buffer, 0, totalRead);
                            if (stringResponse.EndsWith("\r\n"))
                            {
                                try
                                {
                                    offset = 0;
                                    totalRead = 0;
                                    ProcessStringResponse(stringResponse);
                                }
                                catch (JSONParseException e)
                                {
                                    offset = bytes;
                                    Debug.LogWarning("Received what appears to be a partial response or invalid json. Attempting to continue reading. Parsing error: " + e.Message + "\n" + stringResponse);
                                }
                            }
                            else
                            {
                                offset = totalRead;
                            }
                        }

                        // If the final transmission didn't end with \r\n process it as the final
                        // result
                        if (!stringResponse.EndsWith("\r\n") && !string.IsNullOrEmpty(stringResponse))
                        {
                            ProcessStringResponse(stringResponse);
                        }

                        if (stringResponse.Length > 0 && null != responseData)
                        {
                            MainThreadCallback(() => onFullTranscription?.Invoke(responseData["text"]));
                            MainThreadCallback(() => onRawResponse?.Invoke(stringResponse));
                        }
                    }
                    else
                    {
                        using (StreamReader reader = new StreamReader(responseStream))
                        {
                            stringResponse = reader.ReadToEnd();
                            MainThreadCallback(() => onRawResponse?.Invoke(stringResponse));
                            responseData = WitResponseJson.Parse(stringResponse);
                        }
                    }

                    responseStream.Close();
                }
                catch (JSONParseException e)
                {
                    Debug.LogError("Server returned invalid data: " + e.Message + "\n" +
                                   stringResponse);
                    statusCode = ERROR_CODE_INVALID_DATA_FROM_SERVER;
                    statusDescription = "Server returned invalid data.";
                }
                catch (Exception e)
                {
                    Debug.LogError(
                        $"{e.Message}\nRequest Stack Trace:\n{callingStackTrace}\nResponse Stack Trace:\n{e.StackTrace}");
                    statusCode = ERROR_CODE_GENERAL;
                    statusDescription = e.Message;
                }

                response.Close();
            }
            catch (WebException e)
            {
                statusCode = (int) e.Status;
                if (e.Response is HttpWebResponse errorResponse)
                {
                    statusCode = (int) errorResponse.StatusCode;

                    try
                    {
                        var stream = errorResponse.GetResponseStream();
                        if (null != stream)
                        {
                            using (StreamReader reader = new StreamReader(stream))
                            {
                                stringResponse = reader.ReadToEnd();
                                MainThreadCallback(() => onRawResponse?.Invoke(stringResponse));
                                responseData = WitResponseJson.Parse(stringResponse);
                            }
                        }
                    }
                    catch (JSONParseException)
                    {
                        // Response wasn't encoded error, ignore it.
                    }
                    catch (Exception errorResponseError)
                    {
                        // We've already caught that there is an error, we'll ignore any errors
                        // reading error response data and use the status/original error for validation
                        Debug.LogWarning(errorResponseError);
                    }
                }

                statusDescription = e.Message;
                if (e.Status != WebExceptionStatus.RequestCanceled)
                {
                    Debug.LogError(
                        $"Http Request Failed [{statusCode}]: {e.Message}\nRequest Stack Trace:\n{callingStackTrace}\nResponse Stack Trace:\n{e.StackTrace}");
                }
            }
            finally
            {
                isActive = false;
            }

            CloseRequestStream();

            if (null != responseData)
            {
                var error = responseData["error"];
                if (!string.IsNullOrEmpty(error))
                {
                    statusDescription = $"Error: {responseData["code"]}. {error}";
                    statusCode = statusCode == 200 ? ERROR_CODE_GENERAL : statusCode;
                }
            }
            else if (statusCode == 200)
            {
                statusCode = ERROR_CODE_NO_DATA_FROM_SERVER;
                statusDescription = "Server did not return a valid json response.";
                Debug.LogWarning(
                    "No valid data was received from the server even though the request was successful. Actual potential response data: \n" +
                    stringResponse);
            }

            SafeInvoke(onResponse);
        }