Skip to content

Commit

Permalink
Merge pull request #286 from MindscapeHQ/iOS-timout-option
Browse files Browse the repository at this point in the history
iOS timeout option
  • Loading branch information
QuantumNightmare committed Feb 11, 2016
2 parents 013307c + bd49c91 commit eec4ca7
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Mindscape.Raygun4Net.WebApi/readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Providing a custom RaygunClient to the automatic exception handlers
===================================================================

Sometimes when setting up Raygun to send exceptions automatically, you may need to provide a custom RaygunWebApiClient instance in order to use some of the optional feature described below.
To do this, use the static RaygunWebApiClient method overload that takes a function. Within this function, return a new (or previously created) RaygunWebApiClient instance.
To do this, use the static RaygunWebApiClient.Attach method overload that takes a function. Within this function, return a new (or previously created) RaygunWebApiClient instance.
In this function you can setup any additional options on the RaygunWebApiClient instance that you need - more information about each feature is described below.

RaygunWebApiClient.Attach(config, () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public static RaygunEnvironmentMessage Build()
}
catch (Exception ex)
{
Debug.WriteLine("Error retieving screen info: {0}", ex.Message);
Debug.WriteLine("Error retrieving screen info: {0}", ex.Message);
}

try
Expand All @@ -45,7 +45,7 @@ public static RaygunEnvironmentMessage Build()
}
catch (Exception ex)
{
Debug.WriteLine("Error retieving time and locale: {0}", ex.Message);
Debug.WriteLine("Error retrieving time and locale: {0}", ex.Message);
}

try
Expand All @@ -57,7 +57,7 @@ public static RaygunEnvironmentMessage Build()
}
catch (Exception ex)
{
Debug.WriteLine("Error retieving device info: {0}", ex.Message);
Debug.WriteLine("Error retrieving device info: {0}", ex.Message);
}

return message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public IRaygunMessageBuilder SetVersion(string version)
}
catch (Exception ex)
{
Debug.WriteLine("Error retieving package version {0}", ex.Message);
Debug.WriteLine("Error retrieving package version {0}", ex.Message);
}
}

Expand Down
83 changes: 69 additions & 14 deletions Mindscape.Raygun4Net.Xamarin.iOS/RaygunClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public RaygunClient(string apiKey)
_wrapperExceptions.Add(typeof(TargetInvocationException));
_wrapperExceptions.Add(typeof(AggregateException));

ThreadPool.QueueUserWorkItem(state => { SendStoredMessages(); });
ThreadPool.QueueUserWorkItem(state => { SendStoredMessages(0); });
}

private bool ValidateApiKey()
Expand Down Expand Up @@ -101,6 +101,14 @@ public override RaygunIdentifierMessage UserInfo
}
}

/// <summary>
/// Gets or sets the maximum number of milliseconds allowed to attempt a synchronous send to Raygun.
/// A value of 0 will use a timeout of 100 seconds.
/// The default is 0.
/// </summary>
/// <value>The synchronous timeout in milliseconds.</value>
public int SynchronousTimeout { get; set; }

/// <summary>
/// Adds a list of outer exceptions that will be stripped, leaving only the valuable inner exception.
/// This can be used when a wrapper exception, e.g. TargetInvocationException or AggregateException,
Expand Down Expand Up @@ -163,7 +171,7 @@ public void Send(Exception exception, IList<string> tags)
/// <param name="userCustomData">A key-value collection of custom data that will be added to the payload.</param>
public void Send(Exception exception, IList<string> tags, IDictionary userCustomData)
{
StripAndSend(exception, tags, userCustomData);
StripAndSend(exception, tags, userCustomData, SynchronousTimeout);
}

/// <summary>
Expand Down Expand Up @@ -193,7 +201,7 @@ public void SendInBackground(Exception exception, IList<string> tags)
/// <param name="userCustomData">A key-value collection of custom data that will be added to the payload.</param>
public void SendInBackground(Exception exception, IList<string> tags, IDictionary userCustomData)
{
ThreadPool.QueueUserWorkItem(c => StripAndSend(exception, tags, userCustomData));
ThreadPool.QueueUserWorkItem(c => StripAndSend(exception, tags, userCustomData, 0));
}

/// <summary>
Expand All @@ -203,7 +211,7 @@ public void SendInBackground(Exception exception, IList<string> tags, IDictionar
/// set to a valid DateTime and as much of the Details property as is available.</param>
public void SendInBackground(RaygunMessage raygunMessage)
{
ThreadPool.QueueUserWorkItem(c => Send(raygunMessage));
ThreadPool.QueueUserWorkItem(c => Send(raygunMessage, 0));
}

private string DeviceId
Expand Down Expand Up @@ -487,11 +495,11 @@ private RaygunIdentifierMessage BuildRaygunIdentifierMessage(string machineName)
return message;
}

private void StripAndSend(Exception exception, IList<string> tags, IDictionary userCustomData)
private void StripAndSend(Exception exception, IList<string> tags, IDictionary userCustomData, int timeout)
{
foreach (Exception e in StripWrapperExceptions(exception))
{
Send(BuildMessage(e, tags, userCustomData));
Send(BuildMessage(e, tags, userCustomData), timeout);
}
}

Expand Down Expand Up @@ -530,6 +538,11 @@ protected IEnumerable<Exception> StripWrapperExceptions(Exception exception)
/// <param name="raygunMessage">The RaygunMessage to send. This needs its OccurredOn property
/// set to a valid DateTime and as much of the Details property as is available.</param>
public override void Send(RaygunMessage raygunMessage)
{
Send (raygunMessage, SynchronousTimeout);
}

private void Send(RaygunMessage raygunMessage, int timeout)
{
if (ValidateApiKey())
{
Expand All @@ -550,29 +563,31 @@ public override void Send(RaygunMessage raygunMessage)
{
try
{
SaveMessage (message);
SaveMessage(message);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine (string.Format ("Error saving Exception to device {0}", ex.Message));
if (HasInternetConnection)
{
SendMessage (message);
SendMessage(message, timeout);
}
}

if (HasInternetConnection)
// In the case of sending messages during a crash, only send stored messages if there are 2 or less.
// This is to prevent keeping the app open for a long time while it crashes.
if (HasInternetConnection && GetStoredMessageCount() <= 2)
{
SendStoredMessages ();
SendStoredMessages(timeout);
}
}
}
}
}

private bool SendMessage(string message)
private bool SendMessage(string message, int timeout)
{
using (var client = new WebClient())
using (var client = new TimeoutWebClient(timeout))
{
client.Headers.Add("X-ApiKey", _apiKey);
client.Headers.Add("content-type", "application/json; charset=utf-8");
Expand Down Expand Up @@ -613,7 +628,7 @@ private bool HasInternetConnection
}
}

private void SendStoredMessages()
private void SendStoredMessages(int timeout)
{
if (HasInternetConnection)
{
Expand All @@ -630,7 +645,7 @@ private void SendStoredMessages()
using (StreamReader reader = new StreamReader(isoFileStream))
{
string text = reader.ReadToEnd();
bool success = SendMessage(text);
bool success = SendMessage(text, timeout);
// If just one message fails to send, then don't delete the message, and don't attempt sending anymore until later.
if (!success)
{
Expand All @@ -655,6 +670,26 @@ private void SendStoredMessages()
}
}

private int GetStoredMessageCount()
{
try
{
using (IsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isolatedStorage.DirectoryExists("RaygunIO"))
{
string[] fileNames = isolatedStorage.GetFileNames("RaygunIO\\*.txt");
return fileNames.Length;
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(string.Format("Error getting stored message count: {0}", ex.Message));
}
return 0;
}

private void SaveMessage(string message)
{
try
Expand Down Expand Up @@ -707,5 +742,25 @@ private void SaveMessage(string message)
System.Diagnostics.Debug.WriteLine(string.Format("Error saving message to isolated storage {0}", ex.Message));
}
}

private class TimeoutWebClient : WebClient
{
private readonly int _timeout;

public TimeoutWebClient(int timeout)
{
_timeout = timeout;
}

protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (_timeout > 0)
{
request.Timeout = _timeout;
}
return request;
}
}
}
}
2 changes: 1 addition & 1 deletion Mindscape.Raygun4Net.Xamarin.iOS/RaygunMessageBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public IRaygunMessageBuilder SetVersion(string version)
}
catch (Exception ex)
{
Trace.WriteLine("Error retieving bundle version {0}", ex.Message);
Trace.WriteLine("Error retrieving bundle version {0}", ex.Message);
}
}

Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit eec4ca7

Please sign in to comment.