0

I have an API call that returns a query string in json format. Occasionally I get the following response

"<html>\r\n<head><title>502 Bad Gateway</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>502 Bad Gateway</h1></center>\r\n</body>\r\n</html>\r\n"

My code interpreting this response is

string jsonOrdersString = bitmexApi.GetOpenZTOrders(25);//
        List<OrderRecord> newList = JsonConvert.DeserializeObject<List<OrderRecord>>(jsonOrdersString);

This works the majority of the time, until I get an error 502 error. How can I run a check on my json string to see if there is an error and handle it? Its also worth noting that I have many Deserialize Processes in this program, so it would be nice to keep this error handling efficent.

Any help is appreciated, I am new to c# and json and this issue is holding up this project.

Thanks!

Edit: The GetOpenZTOrderS() function calls this Query function. How can I modify this to get also return the status code?

 private string Query(string method, string function, Dictionary<string, string> param = null, bool auth = false, bool json = false)
    {
        string paramData = json ? BuildJSON(param) : BuildQueryData(param);
        string url = "/api/v1" + function + ((method == "GET" && paramData != "") ? "?" + paramData : "");
        string postData = (method != "GET") ? paramData : "";

        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(domain + url);
        webRequest.Method = method;

        if (auth)
        {
            string expires = GetExpires().ToString();
            string message = method + url + expires + postData;
            byte[] signatureBytes = hmacsha256(Encoding.UTF8.GetBytes(apiSecret), Encoding.UTF8.GetBytes(message));
            string signatureString = ByteArrayToString(signatureBytes);

            webRequest.Headers.Add("api-expires", expires);
            webRequest.Headers.Add("api-key", apiKey);
            webRequest.Headers.Add("api-signature", signatureString);
        }

        try
        {
            if (postData != "")
            {
                webRequest.ContentType = json ? "application/json" : "application/x-www-form-urlencoded";
                var data = Encoding.UTF8.GetBytes(postData);
                using (var stream = webRequest.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
            }

            using (WebResponse webResponse = webRequest.GetResponse())
            using (Stream str = webResponse.GetResponseStream())
            using (StreamReader sr = new StreamReader(str))
            {
                return sr.ReadToEnd();
            }
        }
        catch (WebException wex)
        {
            using (HttpWebResponse response = (HttpWebResponse)wex.Response)
            {
                if (response == null)
                    throw;

                using (Stream str = response.GetResponseStream())
                {
                    using (StreamReader sr = new StreamReader(str))
                    {
                        return sr.ReadToEnd();
                    }
                }
            }
        }
    }
Brian K
  • 11
  • 4
  • Do you have access to the code of `bitmexApi.GetOpenZTOrders`? It should be able to return a http status code. – Stefan Mar 01 '20 at 18:11
  • Your `GetOpenZTOrders()` call must not return content of error page. It should check for valid http response code and return some kind of error or null or throw an exception. – Christoph Lütjen Mar 01 '20 at 18:11
  • Yes, I have access to that function. It calls another query function, Ill add it to the post. – Brian K Mar 01 '20 at 19:14

1 Answers1

0

So basically your main problem is in your

GetOpenZTOrders() function, it should return HTTP Status code and then you can simply just check or make switch cases for a different type of status codes.

Http Status Codes

But if you don't access over that function and you just need to make an assumption over the bad design, you can just write the string extension, which will validate the correct JSON.

public static bool IsValidJson(this string stringValue)
{
    if (string.IsNullOrWhiteSpace(stringValue))
    {
        return false;
    }

    var value = stringValue.Trim();

    if ((value.StartsWith("{") && value.EndsWith("}")) || //For object
        (value.StartsWith("[") && value.EndsWith("]"))) //For array
    {
        try
        {
            var obj = JToken.Parse(value);
            return true;
        }
        catch (JsonReaderException)
        {
            return false;
        }
    }

    return false;
}

So mainly it validates the JSON scheme, if it is not correct you will handle the error.

Tornike Gomareli
  • 1,564
  • 2
  • 16
  • 28
  • I will look into making that GetOpenZTOrders() function return the status code as well. For the mean time I think your IsValidJson function will work. Thanks so much! Ill let you know how it works. – Brian K Mar 01 '20 at 19:13
  • typically GetOpenZTOrders() should NOT return the http status code. Http status codes are specific to http transport and should not be exposed. A usual way would be to throw an exception if status code is not a success status code. – Christoph Lütjen Mar 01 '20 at 19:58