JsonSerializationException when trying to get current rate limits.

Aug 16, 2015 at 9:36 PM
Hi,

I updated to version 0.9.9.5 using Nuget and tried to use the app-only authentication and see what the current rate limits were.

The credentials are set like this:
Auth.SetApplicationOnlyCredentials(_consumerKey, _consumerSecret, true);
And I'm trying to get the rate limit using
return RateLimit.GetCurrentCredentialsRateLimits();
When that executes, I get the following error:
Newtonsoft.Json.JsonSerializationException was unhandled by user code
  HResult=-2146233088
  Message=Error setting value to '_rateLimitContext' on 'Tweetinvi.Core.Interfaces.Models.TokenRateLimits'.
  Source=Newtonsoft.Json
  StackTrace:
       at Newtonsoft.Json.Serialization.DynamicValueProvider.SetValue(Object target, Object value)
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
       at Newtonsoft.Json.Serialization.JsonSerializerProxy.DeserializeInternal(JsonReader reader, Type objectType)
       at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
       at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
       at Tweetinvi.Logic.JsonConverters.JsonInterfaceToObjectConverter`2.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
       at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
       at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
       at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
       at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonConverter[] converters)
       at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonConverter[] converters)
       at Tweetinvi.Logic.Wrapper.JsonConvertWrapper.DeserializeObject[T](String json, JsonConverter[] converters)
       at Tweetinvi.Logic.JsonConverters.JsonObjectConverter.DeserializeObject[T](String json, JsonConverter[] converters)
       at Tweetinvi.Credentials.TwitterAccessor.ExecuteGETQuery[T](String query, JsonConverter[] converters)
       at Tweetinvi.Controllers.Help.HelpQueryExecutor.GetCurrentCredentialsRateLimits()
       at Tweetinvi.Controllers.Help.HelpController.GetCurrentCredentialsRateLimits()
       at Tweetinvi.RateLimit.GetCurrentCredentialsRateLimits(Boolean useRateLimitCache)
       at MyApplication.TwitterData.TwitterDataSourcer.GetRateLimits() in TwitterDataSourcer.cs:line 46
  InnerException: System.NullReferenceException
       HResult=-2147467261
       Message=Object reference not set to an instance of an object.
       Source=Tweetinvi.Core
       StackTrace:
            at Tweetinvi.Core.Interfaces.Models.TokenRateLimits.set__rateLimitContext(JObject value)
            at Set_rateLimitContext(Object , Object )
            at Newtonsoft.Json.Serialization.DynamicValueProvider.SetValue(Object target, Object value)
       InnerException: 
Should I be doing things differently? Any guidance would be greatly appreciated.
Aug 25, 2015 at 11:54 AM
Hi,

Thank you for this information, I will have a look into it.
This is probably a bug within Tweetinvi. I will work on this and let you know.

Here is the work item for live notification (https://tweetinvi.codeplex.com/workitem/2638).

Linvi
Aug 25, 2015 at 9:34 PM
Hi Linvi,

Thanks for looking into this.

As per your guide on rate limits, I started to use the TrackAndAwait & QueryBeforeExecute.

However, I noticed that once the limits had been hit the library attempted another fetch resulting in a null result. Moreover, with high volume use where I was using up the search limits quickly and waiting, I kept getting null results for every query and it seems the awaiting wasn't done.

The code I used for setting up the TrackAndAwait & QueryBeforeExecute is below. Please let me know if I did this incorrectly.
         public static void SetCredentials()
        {
            PopulateKeysDictionary();
            _keys.TryGetValue("AccessToken", out _accessToken);
            _keys.TryGetValue("AccessTokenSecret", out _accessTokenSecret);
            _keys.TryGetValue("ConsumerKey", out _consumerKey);
            _keys.TryGetValue("ConsumerSecret", out _consumerSecret);
            Auth.SetUserCredentials(_consumerKey, _consumerSecret, _accessToken, _accessTokenSecret);
            RateLimit.RateLimitTrackerOption = RateLimitTrackerOptions.TrackAndAwait;
            QueryBeforeExecute();
        }
        private static void QueryBeforeExecute()
        {
            TweetinviEvents.QueryBeforeExecute += (sender, args) =>
            {
                var queryRateLimit = RateLimit.GetQueryRateLimit(args.QueryURL);

                if(queryRateLimit != null && queryRateLimit.Remaining == 0)
                {
                    RateLimit.AwaitForQueryRateLimit(queryRateLimit);
                }
            };
        }
Aug 25, 2015 at 10:02 PM
Thank you for these additional information, this is quite helpful.

Please be aware that usually you have to either use RateLimitTrackerOptions.TrackAndAwait; OR RateLimitTrackerOptions.TrackOnly; and QueryBeforeExecute.

I will keep you up to date.

Linvi
Sep 1, 2015 at 1:46 PM
This is now fixed and will be available in the coming release 0.9.9.6.
Sorry for the delay, it took me some time to realize how to reproduce your issue.

The work item has been updated to resolved.

Cheers,
Linvi
Marked as answer by linvi on 9/1/2015 at 5:46 AM