Twitter API code throws an exception exactly every 12 hours

Associate
Joined
1 Dec 2005
Posts
803
This has me a bit baffled. I've got some code that is basically polling Twitter once every 60 seconds to parse any updates to my timeline. There's a bunch of business logic on top because it runs via a task scheduling engine, but it comes down to a relatively simple GET to https://api.twitter.com/1.1/statuses/user_timeline.json.

Every 12 hours, at exactly 1004 and 2204 GMT I get the following exception logged:

Code:
Exception type: System.AggregateException
Exception message: One or more errors occurred.
Exception stack trace:
   at System.Threading.Tasks.Task.WaitAll(Task[] tasks, Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.WaitAll(Task[] tasks, Int32 millisecondsTimeout)
   at System.Threading.Tasks.Task.WaitAll(Task[] tasks)
   at Niknak.Social.Twitter.UserTimeline`1.GetTweets[Tweet,User,Media,MediaSize](String screenName, Int32 count, Boolean includeRTs, String sinceMessageId)
   at NiknakV3.Business.Services.TaskScheduler.Processors.TwitterFeed.ProcessTask(SimpleTaskConfig`1 config, AuditLog currentLog, Boolean& terminate)
Inner exception message: One or more errors occurred.
Inner exception stack trace: 
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at Niknak.Social.Twitter.UserTimeline`1.<>c__DisplayClass3`4.<GetTweets>b__0(Task`1 requestTask)
   at System.Threading.Tasks.ContinuationTaskFromResultTask`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
Inner exception message: An error occurred while sending the request.
Inner exception stack trace:
Inner exception message: The request was aborted: Could not create SSL/TLS secure channel.
Inner exception stack trace: 
   at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)

The important bit is at the bottom:

The request was aborted: Could not create SSL/TLS secure channel.

I think there are a few places from which the problem could stem:

  • Twitter API itself
  • Method calling Twitter
  • Task scheduling logic - some kind of disposal bug perhaps
  • The server/OS/networking on which the Windows Service is running

Here's the code (C#) that's making the call to Twitter:

Code:
public static List<Tweet> GetTweets<Tweet, User, Media, MediaSize>(string screenName, int count, bool includeRTs, string sinceMessageId)
	where Tweet : IMessage, new()
	where User : IUser, new()
	where Media : IMedia, new()
	where MediaSize : IMediaSize, new()
{
	if (string.IsNullOrEmpty(screenName))
		throw new ArgumentNullException("screenName");
	if (count <= 0)
		throw new ArgumentNullException("count");
	if (string.IsNullOrEmpty(sinceMessageId) || sinceMessageId == "0")
		throw new ArgumentNullException("sinceMessageId");

	List<Tweet> outList = new List<Tweet>();
	List<JsonObject> tweets = new List<JsonObject>();

	using (HttpClient client = new HttpClient(new OAuthMessageHandler<OAuthSettings>(new HttpClientHandler())))
	{
		if (client == null)
			throw new Exception("Unable to initiate HttpClient object");

		string requestUrl = string.Format(
			APITIMELINEURL,
			screenName,
			count,
			includeRTs.ToString().ToLower(),
			sinceMessageId
		);

		Task retrieveTweets = client.GetAsync(requestUrl).ContinueWith(requestTask =>
		{
			//get HTTP response from completed task
			HttpResponseMessage response = requestTask.Result;

			//check that response was successful or throw exception
			response.EnsureSuccessStatusCode();

			//necessary when retrieving more than about 15 tweets at a time
			MediaTypeFormatter.SkipStreamLimitChecks = true;

			//read response asynchronously as JsonValue and dump into list for further processing
			Task processTweets = response.Content.ReadAsAsync<JsonArray>().ContinueWith(readTask =>
			{
				JsonArray statuses = readTask.Result;
				foreach (JsonObject status in statuses)
					tweets.Add(status);
			});

			Task.WaitAll(processTweets);
		});

		Task.WaitAll(retrieveTweets);
	}

	if (tweets != null)
		foreach (JsonObject tweet in tweets)
		{
			//we need to do some checks on the message retrieved to ensure it's not fubar
			if (!Utils.IsValidTweetJson(tweet))
				continue;

			outList.Add(Utils.ParseTweetJson<Tweet, User, Media, MediaSize>(tweet));
		}

	return outList;
}

That's part of a library I've published for interacting with social media services (see http://niknaksocial.codeplex.com/). I'm aware of the fact it's running an async method and then just waiting for it, let's ignore that misdemeanor for now ;)

The task scheduling code is also published (see http://niknakservices.codeplex.com/) but I'm fairly confident it's ok since it's quite widely used and tested on other things.

But I'm open to suggestions on what this might be. Has anyone seen anything similar? The closest I've found to the problem is mentioned here. I've not done any network tracing but that's something to try.

Answers on a postcard...? :)
 

sjs

sjs

Associate
Joined
16 Apr 2010
Posts
6
If you alter the schedule, does that change anything? If not, maybe 1004 and 2204 are when the application pool gets recycled.
 
Associate
OP
Joined
1 Dec 2005
Posts
803
If you alter the schedule, does that change anything? If not, maybe 1004 and 2204 are when the application pool gets recycled.
The scheduler works using a start date/time and an interval value, which was set to start at midnight with an interval of 60 seconds. I've changed it to start at 1am and kept the interval, so I'll see if that moves the time of the error by an hour. The request runs in a Windows Service so no app pool to recycle, but good thinking.

Seems your not the only one have the same problem, which oddly enough is exactly the same time as this post click here to view

https://dev.twitter.com/discussions/25590
Looks like the same guy in both unfortunately. I posted in his MSDN thread, think I'll do likewise on Twitter. There are so many moving parts between our requests and the response it could be anywhere causing the problem, but my gut feeling is it's an API issue since it never used to do this...!
 
Associate
OP
Joined
1 Dec 2005
Posts
803
Well I changed the schedule and that didn't make any difference.

BUT

I didn't get the exception come through at 1004 today. Had one last night, but not today. Maybe it's fixed itself...
 
Back
Top Bottom