Skip to content

Commit

Permalink
Version 2.0.6 (#18)
Browse files Browse the repository at this point in the history
* New BacktraceCredentials initialization + UnhandledThreadExeption event flow
  • Loading branch information
konraddysput authored Dec 20, 2018
1 parent 07a4acd commit ad074d1
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 52 deletions.
96 changes: 73 additions & 23 deletions Backtrace.Tests/ClientTests/TestClientCredentials.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Backtrace.Model;
using Backtrace.Model;
using NUnit.Framework;
using System;
namespace Backtrace.Tests.ClientTests
{
/// <summary>
Expand All @@ -21,23 +17,7 @@ public void TestInvalidSectionName(string sectionName)
{
Assert.Throws<InvalidOperationException>(() => new BacktraceClient(sectionName));
}
#endif

[TestCase("InvalidUrl")]
[Test(Author = "Konrad Dysput", Description = "Test invalid api url section")]
public void TestInvalidUrlArgument(string sectionName)
{
//if programmer pass invalid url should throw UriFormatException
//if programmer pass null or empty string as token should throw ArgumentNullException

#if NET35 || NET45
Assert.Throws<UriFormatException>(() => new BacktraceClient(sectionName));
#endif
Assert.Throws<ArgumentException>(() => new BacktraceClient(new BacktraceCredentials("https://test.backtrace.io", string.Empty)));
}


#if NET35 || NET45
[TestCase("EmptyToken")]
[Test(Author = "Konrad Dysput", Description = "Test invalid token section")]
public void TestInvalidTokenArgument(string sectionName)
Expand All @@ -51,8 +31,78 @@ public void TestValidSectionConfiguration(string sectionName)
{
Assert.DoesNotThrow(() => new BacktraceClient(sectionName));
}

#endif

[TestCase("https://backtrace.sp.backtrace.io")]
[TestCase("http://backtrace.sp.backtrace.io")]
[TestCase("http://backtrace.sp.backtrace.io:6098")]
[TestCase("http://backtrace.sp.backtrace.io:7777")]
[TestCase("http://backtrace.sp.backtrace.io:7777/")]
[TestCase("http://backtrace.sp.backtrace.io/")]
[Test(Author = "Konrad Dysput", Description = "Test valid submission url")]
public void GenerateSubmissionUrl_FromValidHostName_ValidSubmissionUrl(string host)
{
const string token = "1234";
var credentials = new BacktraceCredentials(host, token);

string expectedUrl = $"{credentials.BacktraceHostUri.AbsoluteUri}post?format=json&token={credentials.Token}";
Assert.AreEqual(credentials.GetSubmissionUrl(), expectedUrl);
}

[TestCase("https://www.submit.backtrace.io")]
[TestCase("http://www.submit.backtrace.io")]
[TestCase("https://submit.backtrace.io")]
[TestCase("https://submit.backtrace.io/12312/312312/")]
[TestCase("https://submit.backtrace.io/uri/")]
[TestCase("https://submit.backtrace.io/uri?sumbissionToken=123123134&value=123123/")]
[TestCase("http://submit.backtrace.io")]
[TestCase("http://submit.backtrace.io/")]
public void GenerateBacktraceSubmitUrl_FromSubmitUrl_ValidSubmissionUrl(string host)
{
var credentials = new BacktraceCredentials(host);

if (!host.StartsWith("https://") && !host.StartsWith("http://"))
{
host = $"https://{host}";
}

if (!host.EndsWith("/"))
{
host += '/';
}
Assert.AreEqual(host, credentials.GetSubmissionUrl().ToString());
}

[TestCase("")]
[TestCase("not url")]
[TestCase("123123..")]
[Test(Author = "Konrad Dysput", Description = "Test invalid api url")]
public void ThrowInvalidUrlException_FromINvalidUrl_ThrowException(string host)
{
Assert.Throws<UriFormatException>(() => new BacktraceCredentials(host));
Assert.Throws<UriFormatException>(() => new BacktraceCredentials(host, "123"));
}

[TestCase("https://backtrace.sp.backtrace.io")]
[TestCase("http://backtrace.sp.backtrace.io")]
[TestCase("https://totallynoValidSubmitUrl.submit.backtrace.io/")]
[Test(Author = "Konrad Dysput", Description = "Test invalid api url")]
public void ThrowInvalidArgumentException_FromInvalidHostName_ThrowException(string host)
{
Assert.Throws<ArgumentException>(() => new BacktraceCredentials(host));
}

[TestCase("InvalidUrl")]
[Test(Author = "Konrad Dysput", Description = "Test invalid api url section")]
public void TestInvalidUrlArgument(string sectionName)
{
//if programmer pass invalid url should throw UriFormatException
//if programmer pass null or empty string as token should throw ArgumentNullException

#if NET35 || NET45
Assert.Throws<UriFormatException>(() => new BacktraceClient(sectionName));
#endif
Assert.Throws<ArgumentException>(() => new BacktraceClient(new BacktraceCredentials("https://test.backtrace.io", string.Empty)));
}
}
}
8 changes: 4 additions & 4 deletions Backtrace/Backtrace.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@
<TargetFrameworks>netstandard2.0;net45;net35</TargetFrameworks>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageTags>Backtrace Error Diagnostic Tools Debug Bug Bugs StackTrace</PackageTags>
<PackageVersion>2.0.5</PackageVersion>
<PackageVersion>2.0.6</PackageVersion>
<Product>Backtrace</Product>
<PackageLicenseUrl>https://github.com/backtrace-labs/backtrace-csharp/blob/master/LICENSE</PackageLicenseUrl>
<PackageProjectUrl>https://github.com/backtrace-labs/backtrace-csharp</PackageProjectUrl>
<PackageIconUrl>http://backtrace.io/images/icon.png</PackageIconUrl>
<Description>Backtrace's integration with C# applications allows customers to capture and report handled and unhandled C# exceptions to their Backtrace instance, instantly offering the ability to prioritize and debug software errors.</Description>
<RepositoryUrl>https://github.com/backtrace-labs/backtrace-csharp</RepositoryUrl>
<NeutralLanguage>en</NeutralLanguage>
<Version>2.0.5</Version>
<Version>2.0.6</Version>
<Copyright>Backtrace I/O</Copyright>
<Authors>Backtrace I/O</Authors>
<Company>Backtrace I/O</Company>
<AssemblyVersion>2.0.5.0</AssemblyVersion>
<FileVersion>2.0.5.0</FileVersion>
<AssemblyVersion>2.0.6.0</AssemblyVersion>
<FileVersion>2.0.6.0</FileVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
53 changes: 42 additions & 11 deletions Backtrace/Base/BacktraceBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,46 @@ public class BacktraceBase
/// </summary>
public Func<string, string, BacktraceData, BacktraceResult> RequestHandler
{
get => BacktraceApi.RequestHandler;
set => BacktraceApi.RequestHandler = value;
get
{
return BacktraceApi.RequestHandler;
}

set
{
BacktraceApi.RequestHandler = value;
}
}
/// <summary>
/// Set an event executed when received bad request, unauthorize request or other information from server
/// </summary>
public Action<Exception> OnServerError
{
get => BacktraceApi.OnServerError;
set => BacktraceApi.OnServerError = value;
get
{
return BacktraceApi.OnServerError;
}

set
{
BacktraceApi.OnServerError = value;
}
}

/// <summary>
/// Set an event executed when Backtrace API return information about send report
/// </summary>
public Action<BacktraceResult> OnServerResponse
{
get => BacktraceApi.OnServerResponse;
set => BacktraceApi.OnServerResponse = value;
get
{
return BacktraceApi.OnServerResponse;
}

set
{
BacktraceApi.OnServerResponse = value;
}
}

/// <summary>
Expand All @@ -60,7 +81,10 @@ public Action<BacktraceResult> OnServerResponse
/// </summary>
public Action<BacktraceReport> OnClientReportLimitReached
{
set => BacktraceApi.SetClientRateLimitEvent(value);
set
{
BacktraceApi.SetClientRateLimitEvent(value);
}
}

/// <summary>
Expand Down Expand Up @@ -89,7 +113,11 @@ public Action<BacktraceReport> OnClientReportLimitReached
/// </summary>
internal IBacktraceApi BacktraceApi
{
get => _backtraceApi;
get
{
return _backtraceApi;
}

set
{
_backtraceApi = value;
Expand Down Expand Up @@ -218,7 +246,7 @@ public virtual async Task<BacktraceResult> SendAsync(BacktraceReport report)

private async Task<BacktraceResult> HandleAggregateException(BacktraceReport report)
{
AggregateException aggregateException = report.Exception as AggregateException;
var aggregateException = report.Exception as AggregateException;
BacktraceResult result = null;

foreach (var ex in aggregateException.InnerExceptions)
Expand All @@ -232,6 +260,7 @@ private async Task<BacktraceResult> HandleAggregateException(BacktraceReport rep
Factor = report.Factor,
Fingerprint = report.Fingerprint
};

if (result == null)
{
result = await SendAsync(innerReport);
Expand Down Expand Up @@ -272,7 +301,8 @@ public virtual void HandleApplicationException()
/// </summary>
public virtual void HandleApplicationThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
SendAsync(new BacktraceReport(e.Exception)).Wait();
var exception = e.Exception as Exception;
Send(new BacktraceReport(exception));
OnUnhandledApplicationException?.Invoke(e.Exception);
}

Expand All @@ -283,7 +313,8 @@ public virtual void HandleApplicationThreadException(object sender, System.Threa

private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
SendAsync(new BacktraceReport(e.Exception)).Wait();
var exception = e.Exception as Exception;
Send(new BacktraceReport(exception));
OnUnhandledApplicationException?.Invoke(e.Exception);
}

Expand Down
76 changes: 73 additions & 3 deletions Backtrace/Model/BacktraceCredentials.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Text;
Expand All @@ -20,7 +19,13 @@ public class BacktraceCredentials
/// <summary>
/// Get a Uri to Backtrace servcie
/// </summary>
public Uri BacktraceHostUri => _backtraceHostUri;
public Uri BacktraceHostUri
{
get
{
return _backtraceHostUri;
}
}

/// <summary>
/// Get an access token
Expand All @@ -33,6 +38,71 @@ internal string Token
}
}

/// <summary>
/// Create submission url to Backtrace API
/// </summary>
/// <returns></returns>
internal Uri GetSubmissionUrl()
{
if (_backtraceHostUri == null)
{
throw new ArgumentException(nameof(BacktraceHostUri));
}

var uriBuilder = new UriBuilder(BacktraceHostUri);
if (submitUrl)
{
return uriBuilder.Uri;
}
if (string.IsNullOrEmpty(Token))
{
throw new ArgumentException(nameof(Token));
}

if (!uriBuilder.Scheme.StartsWith("http"))
{
uriBuilder.Scheme = $"https://{uriBuilder.Scheme}";
}
if(!uriBuilder.Path.EndsWith("/") && !string.IsNullOrEmpty(uriBuilder.Path))
{
uriBuilder.Path += "/";
}
uriBuilder.Path = $"{uriBuilder.Path}post";
uriBuilder.Query = $"format=json&token={Token}";
return uriBuilder.Uri;
}
private readonly bool submitUrl = false;

/// <summary>
/// Initialize Backtrace credentials with Backtrace submit url.
/// If you pass backtraceSubmitUrl you have to make sure url to API is valid and contains token
/// </summary>
/// <param name="backtraceSubmitUrl">Backtrace submit url</param>
public BacktraceCredentials(
string backtraceSubmitUrl)
: this(new Uri(backtraceSubmitUrl))
{ }

/// <summary>
/// Initialize Backtrace credentials with Backtrace submit url.
/// If you pass backtraceSubmitUrl you have to make sure url to API is valid and contains token
/// </summary>
/// <param name="backtraceSubmitUrl">Backtrace submit url</param>
public BacktraceCredentials(Uri backtraceSubmitUrl)
{
var hostToCheck = backtraceSubmitUrl.Host;
if (!hostToCheck.StartsWith("www."))
{
hostToCheck = $"www.{hostToCheck}";
}
submitUrl = hostToCheck.StartsWith("www.submit.backtrace.io");
if (!submitUrl)
{
throw new ArgumentException(nameof(backtraceSubmitUrl));
}
_backtraceHostUri = backtraceSubmitUrl;
}

/// <summary>
/// Initialize Backtrace credencials
/// </summary>
Expand Down Expand Up @@ -69,7 +139,7 @@ public BacktraceCredentials(
public BacktraceCredentials(
string backtraceHostUrl,
string accessToken)
: this(new Uri(backtraceHostUrl), Encoding.UTF8.GetBytes(accessToken))
: this(backtraceHostUrl, Encoding.UTF8.GetBytes(accessToken))
{ }

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion Backtrace/Services/BacktraceApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public BacktraceApi(BacktraceCredentials credentials, uint reportPerMin = 3)
{
throw new ArgumentException($"{nameof(BacktraceCredentials)} cannot be null");
}
_serverurl = $"{credentials.BacktraceHostUri.AbsoluteUri}post?format=json&token={credentials.Token}";
_serverurl = credentials.GetSubmissionUrl().ToString();
reportLimitWatcher = new ReportLimitWatcher(reportPerMin);
}
#region asyncRequest
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Backtrace C# Release Notes

## Version 2.0.6 - 20.12.2018
- New `BacktraceCredentials` constructor,
- UnhandledThreadException flow

## Version 2.0.5 - 03.12.2018
- Removed unused usings,
- `BacktraceDatabase` conditions with maximum number of records/maximum disk space fix,
Expand Down
7 changes: 0 additions & 7 deletions Examples/Backtrace.WinFoms/Form1.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Backtrace.WinFoms
Expand Down
1 change: 0 additions & 1 deletion Examples/Backtrace.WinFoms/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ static void Main()
backtraceClient = new BacktraceClient(configuartion, database);
//Setting application exceptions
backtraceClient.HandleApplicationException();
backtraceClient.SendAsync("WPF Application crash report started").Wait();
Application.EnableVisualStyles();
Application.ThreadException += backtraceClient.HandleApplicationThreadException;
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Expand Down
Loading

0 comments on commit ad074d1

Please sign in to comment.