From 17f86e50f58dbf9f3974cdb8ea0d845c29012e43 Mon Sep 17 00:00:00 2001 From: Benjamin Pannell Date: Fri, 21 Feb 2014 09:23:14 +0200 Subject: [PATCH 001/171] Updated to NET4.5 for async support --- src/app/SharpRaven/SharpRaven.csproj | 20 +++++++++++--------- src/app/SharpRaven/packages.config | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/app/SharpRaven/SharpRaven.csproj b/src/app/SharpRaven/SharpRaven.csproj index e5aafd0e..b58d39f9 100644 --- a/src/app/SharpRaven/SharpRaven.csproj +++ b/src/app/SharpRaven/SharpRaven.csproj @@ -10,10 +10,11 @@ Properties SharpRaven SharpRaven - v4.0 + v4.5 512 ..\ true + true @@ -24,6 +25,7 @@ prompt 4 bin\Debug\SharpRaven.xml + false pdbonly @@ -33,12 +35,12 @@ prompt 4 bin\Release\SharpRaven.xml + false - False - ..\..\packages\Newtonsoft.Json.5.0.8\lib\net40\Newtonsoft.Json.dll + ..\..\packages\Newtonsoft.Json.5.0.8\lib\net45\Newtonsoft.Json.dll @@ -74,11 +76,11 @@ - \ No newline at end of file diff --git a/src/app/SharpRaven/packages.config b/src/app/SharpRaven/packages.config index 24aa25d9..73ed064f 100644 --- a/src/app/SharpRaven/packages.config +++ b/src/app/SharpRaven/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file From 491a0a70f676d21813639d5e80e726eb6ba11dbf Mon Sep 17 00:00:00 2001 From: Benjamin Pannell Date: Fri, 21 Feb 2014 09:23:30 +0200 Subject: [PATCH 002/171] Add async support to RavenClient --- src/app/SharpRaven/IRavenClient.cs | 35 +++++++ src/app/SharpRaven/RavenClient.cs | 154 ++++++++++++++++++++++++++++- 2 files changed, 187 insertions(+), 2 deletions(-) diff --git a/src/app/SharpRaven/IRavenClient.cs b/src/app/SharpRaven/IRavenClient.cs index 3f9aaca8..d956a588 100644 --- a/src/app/SharpRaven/IRavenClient.cs +++ b/src/app/SharpRaven/IRavenClient.cs @@ -33,6 +33,7 @@ using SharpRaven.Data; using SharpRaven.Logging; +using System.Threading.Tasks; namespace SharpRaven { @@ -81,6 +82,24 @@ string CaptureException(Exception exception, object extra = null); + /// + /// Captures the . + /// + /// The to capture. + /// The optional messge to capture instead of the default . + /// The of the captured . Default: . + /// The tags to annotate the captured with. + /// The extra metadata to send with the captured . + /// + /// The of the successfully captured , or null if it fails. + /// + Task CaptureExceptionAsync(Exception exception, + string message = null, + ErrorLevel level = ErrorLevel.Error, + IDictionary tags = null, + object extra = null); + + /// /// Captures the message. /// @@ -97,6 +116,22 @@ string CaptureMessage(string message, object extra = null); + + /// + /// Captures the message. + /// + /// The message to capture. + /// The of the captured . Default . + /// The tags to annotate the captured with. + /// The extra metadata to send with the captured . + /// + /// The of the successfully captured , or null if it fails. + /// + Task CaptureMessageAsync(string message, + ErrorLevel level = ErrorLevel.Info, + Dictionary tags = null, + object extra = null); + /// /// Captures the event. /// diff --git a/src/app/SharpRaven/RavenClient.cs b/src/app/SharpRaven/RavenClient.cs index 0251cebc..8a4d8f67 100644 --- a/src/app/SharpRaven/RavenClient.cs +++ b/src/app/SharpRaven/RavenClient.cs @@ -38,6 +38,7 @@ using SharpRaven.Data; using SharpRaven.Logging; using SharpRaven.Utilities; +using System.Threading.Tasks; namespace SharpRaven { @@ -128,6 +129,34 @@ public string CaptureException(Exception exception, return Send(packet, CurrentDsn); } + /// + /// Captures the . + /// + /// The to capture. + /// The optional messge to capture. Default: . + /// The of the captured . Default: . + /// The tags to annotate the captured with. + /// The extra metadata to send with the captured . + /// + /// The of the successfully captured , or null if it fails. + /// + public async Task CaptureExceptionAsync(Exception exception, + string message = null, + ErrorLevel level = ErrorLevel.Error, + IDictionary tags = null, + object extra = null) + { + JsonPacket packet = new JsonPacket(CurrentDsn.ProjectID, exception) + { + Message = message ?? exception.Message, + Level = level, + Tags = tags, + Extra = extra + }; + + return await SendAsync(packet, CurrentDsn); + } + /// /// Captures the message. @@ -156,6 +185,33 @@ public string CaptureMessage(string message, } + /// + /// Captures the message. + /// + /// The message to capture. + /// The of the captured . Default . + /// The tags to annotate the captured with. + /// The extra metadata to send with the captured . + /// + /// The of the successfully captured , or null if it fails. + /// + public async Task CaptureMessageAsync(string message, + ErrorLevel level = ErrorLevel.Info, + Dictionary tags = null, + object extra = null) + { + JsonPacket packet = new JsonPacket(CurrentDsn.ProjectID) + { + Message = message, + Level = level, + Tags = tags, + Extra = extra + }; + + return await SendAsync(packet, CurrentDsn); + } + + /// /// Sends the specified packet to Sentry. /// @@ -206,7 +262,7 @@ private string Send(JsonPacket packet, Dsn dsn) { string content = sr.ReadToEnd(); var response = JsonConvert.DeserializeObject(content); - return response.id; + return (string)response.id; } } } @@ -248,10 +304,104 @@ private string Send(JsonPacket packet, Dsn dsn) } } + + + /// + /// Sends the specified packet to Sentry. + /// + /// The packet to send. + /// The Data Source Name in Sentry. + /// + /// The of the successfully captured JSON packet, or null if it fails. + /// + private async Task SendAsync(JsonPacket packet, Dsn dsn) + { + packet.Logger = Logger; + + try + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(dsn.SentryUri); + request.Method = "POST"; + request.Accept = "application/json"; + request.ContentType = "application/json; charset=utf-8"; + request.Headers.Add("X-Sentry-Auth", PacketBuilder.CreateAuthenticationHeader(dsn)); + ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; + request.UserAgent = PacketBuilder.UserAgent; + + // Write the messagebody. + using (Stream s = await request.GetRequestStreamAsync()) + { + using (StreamWriter sw = new StreamWriter(s)) + { + // Compress and encode. + //string data = Utilities.GzipUtil.CompressEncode(packet.Serialize()); + //Console.WriteLine("Writing: " + data); + // Write to the JSON script when ready. + string data = packet.ToString(); + if (LogScrubber != null) + data = LogScrubber.Scrub(data); + + await sw.WriteAsync(data); + } + } + + using (HttpWebResponse wr = (HttpWebResponse)(await request.GetResponseAsync())) + { + using (Stream responseStream = wr.GetResponseStream()) + { + if (responseStream == null) + return null; + + using (StreamReader sr = new StreamReader(responseStream)) + { + string content = await sr.ReadToEndAsync(); + var response = JsonConvert.DeserializeObject(content); + return (string)response.id; + } + } + } + } + catch (WebException e) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.Write("[ERROR] "); + Console.ForegroundColor = ConsoleColor.Gray; + Console.WriteLine(e); + + if (e.Response != null) + { + string messageBody; + using (Stream stream = e.Response.GetResponseStream()) + { + if (stream == null) + return null; + + using (StreamReader sw = new StreamReader(stream)) + { + messageBody = sw.ReadToEnd(); + } + } + + Console.WriteLine("[MESSAGE BODY] " + messageBody); + } + + return null; + } + catch (Exception e) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.Write("[ERROR] "); + Console.ForegroundColor = ConsoleColor.Gray; + Console.WriteLine(e); + + return null; + } + } + #region Deprecated methods /* - * These methods have been deprectaed in favour of the ones + * These methods have been deprecated in favour of the ones * that have the same names as the other sentry clients, this * is purely for the sake of consistency */ From 910226555d9677926374068fc62d74e1de4cd00a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 11 Nov 2014 16:20:05 +0100 Subject: [PATCH 003/171] Moved .NET 4.5 stuff to RavenClient.Net45.cs and added signatures for async methods. --- src/app/SharpRaven/RavenClient.Net45.cs | 199 ++++++++++++++++++++++++ src/app/SharpRaven/RavenClient.cs | 8 +- src/app/SharpRaven/SharpRaven.csproj | 1 + 3 files changed, 201 insertions(+), 7 deletions(-) create mode 100644 src/app/SharpRaven/RavenClient.Net45.cs diff --git a/src/app/SharpRaven/RavenClient.Net45.cs b/src/app/SharpRaven/RavenClient.Net45.cs new file mode 100644 index 00000000..a204fac9 --- /dev/null +++ b/src/app/SharpRaven/RavenClient.Net45.cs @@ -0,0 +1,199 @@ +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System.Collections; +#if !(net40) +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; + + using System.Net.Http; + using System.Net.Http.Headers; + using System.Threading.Tasks; + +using Newtonsoft.Json; + +using SharpRaven.Data; +using SharpRaven.Logging; +using SharpRaven.Utilities; + +namespace SharpRaven +{ + /// + /// The Raven Client, responsible for capturing exceptions and sending them to Sentry. + /// + public partial class RavenClient + { + /// + /// Captures the . + /// + /// The to capture. + /// The optional messge to capture. Default: . + /// The of the captured . Default: . + /// The tags to annotate the captured with. + /// The extra metadata to send with the captured . + /// + /// The of the successfully captured , or null if it fails. + /// + public async Task CaptureExceptionAsync(Exception exception, + SentryMessage message = null, + ErrorLevel level = ErrorLevel.Error, + IDictionary tags = null, + object extra = null) + { + JsonPacket packet = this.jsonPacketFactory.Create(this.currentDsn.ProjectID, + exception, + message, + level, + tags, + extra); + return await SendAsync(packet, CurrentDsn); + } + + + /// + /// Captures the message. + /// + /// The message to capture. + /// The of the captured . Default . + /// The tags to annotate the captured with. + /// The extra metadata to send with the captured . + /// + /// The of the successfully captured , or null if it fails. + /// + public async Task CaptureMessageAsync(SentryMessage message, + ErrorLevel level = ErrorLevel.Info, + Dictionary tags = null, + object extra = null) + { + JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, message, level, tags, extra); + return await SendAsync(packet, CurrentDsn); + } + + + /// + /// Sends the specified packet to Sentry. + /// + /// The packet to send. + /// The Data Source Name in Sentry. + /// + /// The of the successfully captured JSON packet, or null if it fails. + /// + protected async virtual Task SendAsync(JsonPacket packet, Dsn dsn) + { + packet.Logger = Logger; + + try + { + using (HttpClient client = new HttpClient()) + { + // TODO: Implement the below with HttpClient. + } + + var request = (HttpWebRequest)WebRequest.Create(dsn.SentryUri); + request.Timeout = Timeout; + request.ReadWriteTimeout = ReadWriteTimeout; + request.Method = "POST"; + request.Accept = "application/json"; + request.Headers.Add("X-Sentry-Auth", PacketBuilder.CreateAuthenticationHeader(dsn)); + request.UserAgent = PacketBuilder.UserAgent; + + if (Compression) + { + request.Headers.Add(HttpRequestHeader.ContentEncoding, "gzip"); + request.AutomaticDecompression = DecompressionMethods.Deflate; + request.ContentType = "application/octet-stream"; + } + else + request.ContentType = "application/json; charset=utf-8"; + + + string data = packet.ToString(Formatting.None); + + if (LogScrubber != null) + data = LogScrubber.Scrub(data); + + // Write the messagebody. + using (Stream s = request.GetRequestStream()) + { + if (Compression) + GzipUtil.Write(data, s); + else + { + using (StreamWriter sw = new StreamWriter(s)) + sw.Write(data); + } + } + + using (HttpWebResponse wr = (HttpWebResponse)request.GetResponse()) + using (Stream responseStream = wr.GetResponseStream()) + { + if (responseStream == null) + return null; + + using (StreamReader sr = new StreamReader(responseStream)) + { + string content = sr.ReadToEnd(); + var response = JsonConvert.DeserializeObject(content); + return response.id; + } + } + } + catch (Exception exception) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.Write("[ERROR] "); + Console.ForegroundColor = ConsoleColor.Gray; + Console.WriteLine(exception); + + WebException webException = exception as WebException; + if (webException != null && webException.Response != null) + { + string messageBody; + using (Stream stream = webException.Response.GetResponseStream()) + { + if (stream == null) + return null; + + using (StreamReader sw = new StreamReader(stream)) + messageBody = sw.ReadToEnd(); + } + + Console.WriteLine("[MESSAGE BODY] " + messageBody); + } + } + + return null; + } + } +} + +#endif \ No newline at end of file diff --git a/src/app/SharpRaven/RavenClient.cs b/src/app/SharpRaven/RavenClient.cs index 137ba997..e87f2af8 100644 --- a/src/app/SharpRaven/RavenClient.cs +++ b/src/app/SharpRaven/RavenClient.cs @@ -33,12 +33,6 @@ using System.IO; using System.Net; -#if !(net40) - using System.Net.Http; - using System.Net.Http.Headers; - using System.Threading.Tasks; -#endif - using Newtonsoft.Json; using SharpRaven.Data; @@ -50,7 +44,7 @@ namespace SharpRaven /// /// The Raven Client, responsible for capturing exceptions and sending them to Sentry. /// - public class RavenClient : IRavenClient + public partial class RavenClient : IRavenClient { private readonly Dsn currentDsn; private readonly IJsonPacketFactory jsonPacketFactory; diff --git a/src/app/SharpRaven/SharpRaven.csproj b/src/app/SharpRaven/SharpRaven.csproj index c63214c1..9782d036 100644 --- a/src/app/SharpRaven/SharpRaven.csproj +++ b/src/app/SharpRaven/SharpRaven.csproj @@ -94,6 +94,7 @@ + From bbf72e30d8b6357286f9179ee667f1f43c17e456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 11 Nov 2014 16:25:57 +0100 Subject: [PATCH 004/171] Set the Timeout property on the HttpClient. --- src/app/SharpRaven/RavenClient.Net45.cs | 99 +++---------------------- 1 file changed, 11 insertions(+), 88 deletions(-) diff --git a/src/app/SharpRaven/RavenClient.Net45.cs b/src/app/SharpRaven/RavenClient.Net45.cs index a204fac9..f41da10f 100644 --- a/src/app/SharpRaven/RavenClient.Net45.cs +++ b/src/app/SharpRaven/RavenClient.Net45.cs @@ -28,22 +28,13 @@ #endregion -using System.Collections; #if !(net40) using System; using System.Collections.Generic; -using System.IO; -using System.Net; - - using System.Net.Http; - using System.Net.Http.Headers; - using System.Threading.Tasks; - -using Newtonsoft.Json; +using System.Net.Http; +using System.Threading.Tasks; using SharpRaven.Data; -using SharpRaven.Logging; -using SharpRaven.Utilities; namespace SharpRaven { @@ -64,10 +55,10 @@ public partial class RavenClient /// The of the successfully captured , or null if it fails. /// public async Task CaptureExceptionAsync(Exception exception, - SentryMessage message = null, - ErrorLevel level = ErrorLevel.Error, - IDictionary tags = null, - object extra = null) + SentryMessage message = null, + ErrorLevel level = ErrorLevel.Error, + IDictionary tags = null, + object extra = null) { JsonPacket packet = this.jsonPacketFactory.Create(this.currentDsn.ProjectID, exception, @@ -90,9 +81,9 @@ public async Task CaptureExceptionAsync(Exception exception, /// The of the successfully captured , or null if it fails. /// public async Task CaptureMessageAsync(SentryMessage message, - ErrorLevel level = ErrorLevel.Info, - Dictionary tags = null, - object extra = null) + ErrorLevel level = ErrorLevel.Info, + Dictionary tags = null, + object extra = null) { JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, message, level, tags, extra); return await SendAsync(packet, CurrentDsn); @@ -107,7 +98,7 @@ public async Task CaptureMessageAsync(SentryMessage message, /// /// The of the successfully captured JSON packet, or null if it fails. /// - protected async virtual Task SendAsync(JsonPacket packet, Dsn dsn) + protected virtual async Task SendAsync(JsonPacket packet, Dsn dsn) { packet.Logger = Logger; @@ -116,79 +107,11 @@ protected async virtual Task SendAsync(JsonPacket packet, Dsn dsn) using (HttpClient client = new HttpClient()) { // TODO: Implement the below with HttpClient. - } - - var request = (HttpWebRequest)WebRequest.Create(dsn.SentryUri); - request.Timeout = Timeout; - request.ReadWriteTimeout = ReadWriteTimeout; - request.Method = "POST"; - request.Accept = "application/json"; - request.Headers.Add("X-Sentry-Auth", PacketBuilder.CreateAuthenticationHeader(dsn)); - request.UserAgent = PacketBuilder.UserAgent; - - if (Compression) - { - request.Headers.Add(HttpRequestHeader.ContentEncoding, "gzip"); - request.AutomaticDecompression = DecompressionMethods.Deflate; - request.ContentType = "application/octet-stream"; - } - else - request.ContentType = "application/json; charset=utf-8"; - - - string data = packet.ToString(Formatting.None); - - if (LogScrubber != null) - data = LogScrubber.Scrub(data); - - // Write the messagebody. - using (Stream s = request.GetRequestStream()) - { - if (Compression) - GzipUtil.Write(data, s); - else - { - using (StreamWriter sw = new StreamWriter(s)) - sw.Write(data); - } - } - - using (HttpWebResponse wr = (HttpWebResponse)request.GetResponse()) - using (Stream responseStream = wr.GetResponseStream()) - { - if (responseStream == null) - return null; - - using (StreamReader sr = new StreamReader(responseStream)) - { - string content = sr.ReadToEnd(); - var response = JsonConvert.DeserializeObject(content); - return response.id; - } + client.Timeout = Timeout; } } catch (Exception exception) { - Console.ForegroundColor = ConsoleColor.Red; - Console.Write("[ERROR] "); - Console.ForegroundColor = ConsoleColor.Gray; - Console.WriteLine(exception); - - WebException webException = exception as WebException; - if (webException != null && webException.Response != null) - { - string messageBody; - using (Stream stream = webException.Response.GetResponseStream()) - { - if (stream == null) - return null; - - using (StreamReader sw = new StreamReader(stream)) - messageBody = sw.ReadToEnd(); - } - - Console.WriteLine("[MESSAGE BODY] " + messageBody); - } } return null; From 8fedab5b4a6b16b2bfc4d218fda71022ab2db7ca Mon Sep 17 00:00:00 2001 From: Patrizio Bertozzi Date: Thu, 13 Nov 2014 22:32:05 +0100 Subject: [PATCH 005/171] Initial setup of SharpRaven.Nancy --- src/SharpRaven.sln | 23 ++ .../SharpRaven.Nancy/ApplicationStartup.cs | 35 +++ src/app/SharpRaven.Nancy/Configuration.cs | 65 ++++++ .../SharpRaven.Nancy/Data/SentryRequest.cs | 212 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 45 ++++ src/app/SharpRaven.Nancy/RavenClient.cs | 60 +++++ .../SharpRaven.Nancy/SharpRaven.Nancy.csproj | 93 ++++++++ src/app/SharpRaven.Nancy/packages.config | 5 + src/app/SharpRaven/Configuration.cs | 42 ++++ src/app/SharpRaven/Data/ISentryRequest.cs | 103 +++++++++ src/app/SharpRaven/Data/JsonPacket.cs | 2 +- src/app/SharpRaven/Data/SentryRequest.cs | 2 +- src/app/SharpRaven/RavenClient.cs | 12 + src/app/SharpRaven/SharpRaven.csproj | 3 + src/packages/repositories.config | 1 + 15 files changed, 701 insertions(+), 2 deletions(-) create mode 100644 src/app/SharpRaven.Nancy/ApplicationStartup.cs create mode 100644 src/app/SharpRaven.Nancy/Configuration.cs create mode 100644 src/app/SharpRaven.Nancy/Data/SentryRequest.cs create mode 100644 src/app/SharpRaven.Nancy/Properties/AssemblyInfo.cs create mode 100644 src/app/SharpRaven.Nancy/RavenClient.cs create mode 100644 src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj create mode 100644 src/app/SharpRaven.Nancy/packages.config create mode 100644 src/app/SharpRaven/Configuration.cs create mode 100644 src/app/SharpRaven/Data/ISentryRequest.cs diff --git a/src/SharpRaven.sln b/src/SharpRaven.sln index cf9d5586..3703dec0 100644 --- a/src/SharpRaven.sln +++ b/src/SharpRaven.sln @@ -25,6 +25,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution SharpRaven.build = SharpRaven.build EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpRaven.Nancy", "app\SharpRaven.Nancy\SharpRaven.Nancy.csproj", "{ABE22746-6EEB-4970-A608-C02BC3B8BDA3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug 4.0|Any CPU = Debug 4.0|Any CPU @@ -101,6 +103,26 @@ Global {156621FC-2C48-4CDF-A368-9347BABE9089}.Release 4.5|Mixed Platforms.ActiveCfg = Release 4.5|Any CPU {156621FC-2C48-4CDF-A368-9347BABE9089}.Release 4.5|Mixed Platforms.Build.0 = Release 4.5|Any CPU {156621FC-2C48-4CDF-A368-9347BABE9089}.Release 4.5|x86.ActiveCfg = Release 4.5|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Debug 4.0|Any CPU.ActiveCfg = Debug 4.0|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Debug 4.0|Any CPU.Build.0 = Debug 4.0|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Debug 4.0|Mixed Platforms.ActiveCfg = Debug 4.0|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Debug 4.0|Mixed Platforms.Build.0 = Debug 4.0|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Debug 4.0|x86.ActiveCfg = Debug 4.0|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Debug 4.5|Mixed Platforms.ActiveCfg = Debug 4.5|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Debug 4.5|Mixed Platforms.Build.0 = Debug 4.5|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Debug 4.5|x86.ActiveCfg = Debug 4.5|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Release 4.0|Any CPU.ActiveCfg = Release 4.0|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Release 4.0|Any CPU.Build.0 = Release 4.0|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Release 4.0|Mixed Platforms.ActiveCfg = Release 4.0|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Release 4.0|Mixed Platforms.Build.0 = Release 4.0|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Release 4.0|x86.ActiveCfg = Release 4.0|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Release 4.5|Mixed Platforms.ActiveCfg = Release 4.5|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Release 4.5|Mixed Platforms.Build.0 = Release 4.5|Any CPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3}.Release 4.5|x86.ActiveCfg = Release 4.5|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -109,5 +131,6 @@ Global {CC80A2E1-AE39-44DE-8DA3-4EEF42F90FB1} = {88CB5CD6-ACFA-441E-9FBB-E1E06F181B89} {E1DBEBBF-9448-4D99-B378-2B8CF1629F31} = {D2B3990A-A048-49F3-A697-A1DAEF82CE7F} {156621FC-2C48-4CDF-A368-9347BABE9089} = {D2B3990A-A048-49F3-A697-A1DAEF82CE7F} + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3} = {88CB5CD6-ACFA-441E-9FBB-E1E06F181B89} EndGlobalSection EndGlobal diff --git a/src/app/SharpRaven.Nancy/ApplicationStartup.cs b/src/app/SharpRaven.Nancy/ApplicationStartup.cs new file mode 100644 index 00000000..862641bd --- /dev/null +++ b/src/app/SharpRaven.Nancy/ApplicationStartup.cs @@ -0,0 +1,35 @@ +using System; +using System.Configuration; +using Nancy.Bootstrapper; +using Nancy; +using System.Threading; + +namespace SharpRaven.Nancy +{ + public class ApplicationStartup : IApplicationStartup + { + public void Initialize(IPipelines pipelines) + { + var sharpRaven = new PipelineItem>( + Configuration.Settings.PipelineName.Value, (context, exception) => + { + Thread.SetData( + Thread.GetNamedDataSlot("SharpRaven.Nancy.NancyContext"), + context); + + if (Configuration.Settings.CaptureExceptionOnError.Value) + { + IRavenClient client = new RavenClient(context); + + client.CaptureException(exception); + } + + return null; + }); + + pipelines.OnError.AddItemToStartOfPipeline(sharpRaven); + } + } +} + + diff --git a/src/app/SharpRaven.Nancy/Configuration.cs b/src/app/SharpRaven.Nancy/Configuration.cs new file mode 100644 index 00000000..06de5047 --- /dev/null +++ b/src/app/SharpRaven.Nancy/Configuration.cs @@ -0,0 +1,65 @@ +using System; +using System.Configuration; + +namespace SharpRaven.Nancy +{ + public class Configuration : SharpRaven.Configuration + { + private const string pipelineNameKey = "pipelineName"; + private const string captureExceptionOnErrorKey = "captureExceptionOnError"; + private static readonly Configuration settings = + ConfigurationManager.GetSection("sharpRaven") as Configuration; + + public static Configuration Settings + { + get + { + return settings; + } + } + + [ConfigurationProperty(pipelineNameKey, IsKey = true)] + public PipelineNameElement PipelineName + { + get { return (PipelineNameElement)base[pipelineNameKey]; } + } + + public class PipelineNameElement : ConfigurationElement + { + [ConfigurationProperty("value", DefaultValue = "SharpRaven.Nancy")] + public String Value + { + get + { + return (string)this["value"]; + } + set + { + this["value"] = value; + } + } + } + + [ConfigurationProperty(captureExceptionOnErrorKey, IsKey = true)] + public CaptureExceptionOnErrorElement CaptureExceptionOnError + { + get { return (CaptureExceptionOnErrorElement)base[captureExceptionOnErrorKey]; } + } + + public class CaptureExceptionOnErrorElement : ConfigurationElement + { + [ConfigurationProperty("value", DefaultValue = "true")] + public bool Value + { + get + { + return (bool)this["value"]; + } + set + { + this["value"] = value; + } + } + } + } +} diff --git a/src/app/SharpRaven.Nancy/Data/SentryRequest.cs b/src/app/SharpRaven.Nancy/Data/SentryRequest.cs new file mode 100644 index 00000000..b0c67295 --- /dev/null +++ b/src/app/SharpRaven.Nancy/Data/SentryRequest.cs @@ -0,0 +1,212 @@ +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Reflection; +using System.Security.Principal; +using Newtonsoft.Json; +using System.Text; +using System.Threading; +using System.IO; +using NancyIO = Nancy.IO; +using Nancy; +using SharpRaven.Data; + +namespace SharpRaven.Nancy.Data +{ + /// + /// The Request information is stored in the Http interface. Two arguments are required: url and method. + /// + public class SentryRequest : ISentryRequest + { + private readonly NancyContext httpContext; + + [JsonIgnore] + private bool HasHttpContext + { + get { return this.httpContext != null; } + } + + internal SentryRequest(NancyContext httpContext) + { + this.httpContext = httpContext; + + if (!HasHttpContext) + { + return; + } + + // Url and Method + this.Url = this.httpContext.Request.Url.ToString(); + this.Method = this.httpContext.Request.Method; + + // Data + NancyIO.RequestStream requestStream = this.httpContext.Request.Body; + + if (requestStream.Length > 0 && requestStream.CanRead && requestStream.CanSeek) + { + // seek the stream to begin + requestStream.Seek(0, SeekOrigin.Begin); + + StreamReader reader = new StreamReader(requestStream); + + // read data + this.Data = reader.ReadToEnd(); + } + + // QueryString + string qs = string.Empty; + foreach (var item in this.httpContext.Request.Query) + { + qs += item + "=" + this.httpContext.Request.Query[item] + "&"; + } + + this.QueryString = qs.TrimEnd(new char[] { '&' }); + + // Cookies + this.Cookies = this.httpContext.Request.Cookies; + + // Headers + this.Headers = this.httpContext.Request.Headers + .Select(s => new + { + Key = s.Key, + Value = s.Value.Aggregate(new StringBuilder(), (stringBuilder, argument) => + { + stringBuilder.Append(argument + " "); + + return stringBuilder; + }) + .ToString() + .TrimEnd(new char[] { ' ' }) + }) + .ToDictionary(k => k.Key, v => v.Value); + } + + /// + /// Gets or sets the cookies. + /// + /// + /// The cookies. + /// + [JsonProperty(PropertyName = "cookies", NullValueHandling = NullValueHandling.Ignore)] + public IDictionary Cookies { get; set; } + + /// + /// The data variable should only contain the request body (not the query string). It can either be a dictionary (for standard HTTP requests) or a raw request body. + /// + /// + /// The data. + /// + [JsonProperty(PropertyName = "data", NullValueHandling = NullValueHandling.Ignore)] + public object Data { get; set; } + + /// + /// The env variable is a compounded dictionary of HTTP headers as well as environment information passed from the webserver. + /// Sentry will explicitly look for REMOTE_ADDR in env for things which require an IP address. + /// + /// + /// The environment. + /// + [JsonProperty(PropertyName = "env", NullValueHandling = NullValueHandling.Ignore)] + public IDictionary Environment { get; set; } + + /// + /// Gets or sets the headers. + /// + /// + /// The headers. + /// + [JsonProperty(PropertyName = "headers", NullValueHandling = NullValueHandling.Ignore)] + public IDictionary Headers { get; set; } + + /// + /// Gets or sets the method of the HTTP request. + /// + /// + /// The method of the HTTP request. + /// + [JsonProperty(PropertyName = "method", NullValueHandling = NullValueHandling.Ignore)] + public string Method { get; set; } + + /// + /// Gets or sets the query string. + /// + /// + /// The query string. + /// + [JsonProperty(PropertyName = "query_string", NullValueHandling = NullValueHandling.Ignore)] + public string QueryString { get; set; } + + /// + /// Gets or sets the URL of the HTTP request. + /// + /// + /// The URL of the HTTP request. + /// + [JsonProperty(PropertyName = "url", NullValueHandling = NullValueHandling.Ignore)] + public string Url { get; set; } + + /// + /// Gets the user. + /// + /// + /// If an HTTP context is available, an instance of , otherwise null. + /// + public SentryUser GetUser() + { + if (!HasHttpContext || this.httpContext.CurrentUser == null) + { + return null; + } + + return new SentryUser(this.httpContext.CurrentUser.UserName) + { + IpAddress = this.httpContext.Request.UserHostAddress + }; + } + + /// + /// Gets the request. + /// + /// + /// If an HTTP contest is available, an instance of , otherwise null. + /// + public static SentryRequest GetRequest(NancyContext httpContext) + { + var request = new SentryRequest(httpContext); + + return request.HasHttpContext ? request : null; + } + } +} \ No newline at end of file diff --git a/src/app/SharpRaven.Nancy/Properties/AssemblyInfo.cs b/src/app/SharpRaven.Nancy/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..98257b7e --- /dev/null +++ b/src/app/SharpRaven.Nancy/Properties/AssemblyInfo.cs @@ -0,0 +1,45 @@ +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("SharpRaven.Nancy")] +[assembly: AssemblyDescription("SharpRaven is a C# client for Sentry https://www.getsentry.com running on Nancy")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Sentry")] +[assembly: AssemblyProduct("SharpRaven.Nancy")] +[assembly: AssemblyCopyright("Copyright © Sentry 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] +[assembly: Guid("48817F2C-4A13-42B5-B362-EF00A957F2D5")] +[assembly: InternalsVisibleTo("SharpRaven.UnitTests")] \ No newline at end of file diff --git a/src/app/SharpRaven.Nancy/RavenClient.cs b/src/app/SharpRaven.Nancy/RavenClient.cs new file mode 100644 index 00000000..cab6529e --- /dev/null +++ b/src/app/SharpRaven.Nancy/RavenClient.cs @@ -0,0 +1,60 @@ +using Nancy; +using SharpRaven.Data; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using NancyIO = Nancy.IO; + +namespace SharpRaven.Nancy +{ + /// + /// The Raven Client, responsible for capturing exceptions and sending them to Sentry. + /// + public class RavenClient : SharpRaven.RavenClient + { + private NancyContext httpContext; + + /// + /// Initializes a new instance of the class. Sentry + /// Data Source Name will be read from sharpRaven section in your app.config or + /// web.config. + /// + /// The optional that will be used to fill that will be sent to Sentry. + /// The optional factory that will be used to create the that will be sent to Sentry. + public RavenClient(NancyContext httpContext = null, IJsonPacketFactory jsonPacketFactory = null) + : base(new Dsn(Configuration.Settings.Dsn.Value), jsonPacketFactory) + { + this.httpContext = httpContext; + } + + /// + /// Sends the specified packet to Sentry. + /// + /// The packet to send. + /// The Data Source Name in Sentry. + /// + /// The of the successfully captured JSON packet, or null if it fails. + /// + protected override string Send(JsonPacket packet, Dsn dsn) + { + // looking for NancyContext + this.httpContext = this.httpContext ?? Thread.GetData( + Thread.GetNamedDataSlot("SharpRaven.Nancy.NancyContext")) as NancyContext; + + // get SentryRequest + ISentryRequest sentryRequest = Nancy.Data.SentryRequest.GetRequest(this.httpContext); + + // patch JsonPacket.Request with data on NancyContext + packet.Request = sentryRequest; + + // patch JsonPacket.User with data on NancyContext + packet.User = sentryRequest.GetUser(); + + return base.Send(packet, dsn); + } + } +} diff --git a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj new file mode 100644 index 00000000..11c18751 --- /dev/null +++ b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj @@ -0,0 +1,93 @@ + + + + + Debug + AnyCPU + {ABE22746-6EEB-4970-A608-C02BC3B8BDA3} + Library + Properties + SharpRaven.Nancy + SharpRaven.Nancy + v4.5 + 512 + + + + true + bin\Debug\net40\ + TRACE;DEBUG;net40 + full + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + true + bin\Debug\net45\ + DEBUG;TRACE + full + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + bin\Release\net40\ + TRACE;net40 + true + pdbonly + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + bin\Release\net45\ + TRACE + true + pdbonly + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + + ..\..\packages\Nancy.0.23.2\lib\net40\Nancy.dll + + + False + ..\..\packages\Newtonsoft.Json.6.0.6\lib\net45\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + + + + {cc80a2e1-ae39-44de-8da3-4eef42f90fb1} + SharpRaven + + + + + + + + \ No newline at end of file diff --git a/src/app/SharpRaven.Nancy/packages.config b/src/app/SharpRaven.Nancy/packages.config new file mode 100644 index 00000000..546f9bfa --- /dev/null +++ b/src/app/SharpRaven.Nancy/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/app/SharpRaven/Configuration.cs b/src/app/SharpRaven/Configuration.cs new file mode 100644 index 00000000..0de745ef --- /dev/null +++ b/src/app/SharpRaven/Configuration.cs @@ -0,0 +1,42 @@ +using System; +using System.Configuration; + +namespace SharpRaven +{ + public class Configuration : ConfigurationSection + { + private const string dsnKey = "dsn"; + private static readonly Configuration settings = + ConfigurationManager.GetSection("sharpRaven") as Configuration; + + public static Configuration Settings + { + get + { + return settings; + } + } + + [ConfigurationProperty(dsnKey, IsKey = true)] + public DsnElement Dsn + { + get { return (DsnElement)base[dsnKey]; } + } + + public class DsnElement : ConfigurationElement + { + [ConfigurationProperty("value")] + public String Value + { + get + { + return (String)this["value"]; + } + set + { + this["value"] = value; + } + } + } + } +} diff --git a/src/app/SharpRaven/Data/ISentryRequest.cs b/src/app/SharpRaven/Data/ISentryRequest.cs new file mode 100644 index 00000000..0631675a --- /dev/null +++ b/src/app/SharpRaven/Data/ISentryRequest.cs @@ -0,0 +1,103 @@ +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; + +namespace SharpRaven.Data +{ + public interface ISentryRequest + { + /// + /// Gets or sets the cookies. + /// + /// + /// The cookies. + /// + IDictionary Cookies { get; set; } + + /// + /// The data variable should only contain the request body (not the query string). It can either be a dictionary (for standard HTTP requests) or a raw request body. + /// + /// + /// The data. + /// + object Data { get; set; } + + /// + /// The env variable is a compounded dictionary of HTTP headers as well as environment information passed from the webserver. + /// Sentry will explicitly look for REMOTE_ADDR in env for things which require an IP address. + /// + /// + /// The environment. + /// + IDictionary Environment { get; set; } + + /// + /// Gets or sets the headers. + /// + /// + /// The headers. + /// + IDictionary Headers { get; set; } + + /// + /// Gets or sets the method of the HTTP request. + /// + /// + /// The method of the HTTP request. + /// + string Method { get; set; } + + /// + /// Gets or sets the query string. + /// + /// + /// The query string. + /// + string QueryString { get; set; } + + /// + /// Gets or sets the URL of the HTTP request. + /// + /// + /// The URL of the HTTP request. + /// + string Url { get; set; } + + /// + /// Gets the user. + /// + /// + /// If an HTTP context is available, an instance of , otherwise null. + /// + SentryUser GetUser(); + } +} \ No newline at end of file diff --git a/src/app/SharpRaven/Data/JsonPacket.cs b/src/app/SharpRaven/Data/JsonPacket.cs index 8b7cf15d..8082bcab 100644 --- a/src/app/SharpRaven/Data/JsonPacket.cs +++ b/src/app/SharpRaven/Data/JsonPacket.cs @@ -226,7 +226,7 @@ private JsonPacket() /// The object, containing information about the HTTP request. /// [JsonProperty(PropertyName = "request", NullValueHandling = NullValueHandling.Ignore)] - public SentryRequest Request { get; set; } + public ISentryRequest Request { get; set; } /// /// Identifies the host client from which the event was recorded. diff --git a/src/app/SharpRaven/Data/SentryRequest.cs b/src/app/SharpRaven/Data/SentryRequest.cs index f9155eba..42d18242 100644 --- a/src/app/SharpRaven/Data/SentryRequest.cs +++ b/src/app/SharpRaven/Data/SentryRequest.cs @@ -42,7 +42,7 @@ namespace SharpRaven.Data /// /// The Request information is stored in the Http interface. Two arguments are required: url and method. /// - public class SentryRequest + public class SentryRequest : ISentryRequest { private readonly dynamic httpContext; diff --git a/src/app/SharpRaven/RavenClient.cs b/src/app/SharpRaven/RavenClient.cs index 0d530f40..9b2a3cff 100644 --- a/src/app/SharpRaven/RavenClient.cs +++ b/src/app/SharpRaven/RavenClient.cs @@ -56,6 +56,18 @@ public class RavenClient : IRavenClient private readonly IJsonPacketFactory jsonPacketFactory; + /// + /// Initializes a new instance of the class. Sentry + /// Data Source Name will be read from sharpRaven section in your app.config or + /// web.config. + /// + /// The optional factory that will be used to create the that will be sent to Sentry. + public RavenClient(IJsonPacketFactory jsonPacketFactory = null) + : this(new Dsn(Configuration.Settings.Dsn.Value), jsonPacketFactory) + { + } + + /// /// Initializes a new instance of the class. /// diff --git a/src/app/SharpRaven/SharpRaven.csproj b/src/app/SharpRaven/SharpRaven.csproj index c63214c1..e5489587 100644 --- a/src/app/SharpRaven/SharpRaven.csproj +++ b/src/app/SharpRaven/SharpRaven.csproj @@ -71,9 +71,11 @@ ..\..\packages\Newtonsoft.Json.6.0.6\lib\net40\Newtonsoft.Json.dll + + @@ -96,6 +98,7 @@ + diff --git a/src/packages/repositories.config b/src/packages/repositories.config index 1550bc61..fdb1f0c0 100644 --- a/src/packages/repositories.config +++ b/src/packages/repositories.config @@ -1,5 +1,6 @@  + \ No newline at end of file From 6f4c329d3b191552db9e809b61df9a32689364d7 Mon Sep 17 00:00:00 2001 From: Patrizio Bertozzi Date: Thu, 13 Nov 2014 22:41:20 +0100 Subject: [PATCH 006/171] Refactoring to avoid duplicate of string "SharpRaven.Nancy.NancyContext" --- .../SharpRaven.Nancy/ApplicationStartup.cs | 2 +- src/app/SharpRaven.Nancy/Configuration.cs | 24 +++++++++++++++---- src/app/SharpRaven.Nancy/RavenClient.cs | 11 ++------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/app/SharpRaven.Nancy/ApplicationStartup.cs b/src/app/SharpRaven.Nancy/ApplicationStartup.cs index 862641bd..a8bff2b3 100644 --- a/src/app/SharpRaven.Nancy/ApplicationStartup.cs +++ b/src/app/SharpRaven.Nancy/ApplicationStartup.cs @@ -14,7 +14,7 @@ public void Initialize(IPipelines pipelines) Configuration.Settings.PipelineName.Value, (context, exception) => { Thread.SetData( - Thread.GetNamedDataSlot("SharpRaven.Nancy.NancyContext"), + Thread.GetNamedDataSlot(Configuration.Settings.NancyContextDataSlot), context); if (Configuration.Settings.CaptureExceptionOnError.Value) diff --git a/src/app/SharpRaven.Nancy/Configuration.cs b/src/app/SharpRaven.Nancy/Configuration.cs index 06de5047..0a1461a9 100644 --- a/src/app/SharpRaven.Nancy/Configuration.cs +++ b/src/app/SharpRaven.Nancy/Configuration.cs @@ -12,16 +12,27 @@ public class Configuration : SharpRaven.Configuration public static Configuration Settings { - get - { - return settings; + get + { + return settings; + } + } + + public string NancyContextDataSlot + { + get + { + return "SharpRaven.Nancy.NancyContext"; } } [ConfigurationProperty(pipelineNameKey, IsKey = true)] public PipelineNameElement PipelineName { - get { return (PipelineNameElement)base[pipelineNameKey]; } + get + { + return (PipelineNameElement)base[pipelineNameKey]; + } } public class PipelineNameElement : ConfigurationElement @@ -43,7 +54,10 @@ public String Value [ConfigurationProperty(captureExceptionOnErrorKey, IsKey = true)] public CaptureExceptionOnErrorElement CaptureExceptionOnError { - get { return (CaptureExceptionOnErrorElement)base[captureExceptionOnErrorKey]; } + get + { + return (CaptureExceptionOnErrorElement)base[captureExceptionOnErrorKey]; + } } public class CaptureExceptionOnErrorElement : ConfigurationElement diff --git a/src/app/SharpRaven.Nancy/RavenClient.cs b/src/app/SharpRaven.Nancy/RavenClient.cs index cab6529e..58e7842c 100644 --- a/src/app/SharpRaven.Nancy/RavenClient.cs +++ b/src/app/SharpRaven.Nancy/RavenClient.cs @@ -1,13 +1,6 @@ using Nancy; using SharpRaven.Data; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; using System.Threading; -using System.Threading.Tasks; -using NancyIO = Nancy.IO; namespace SharpRaven.Nancy { @@ -43,10 +36,10 @@ protected override string Send(JsonPacket packet, Dsn dsn) { // looking for NancyContext this.httpContext = this.httpContext ?? Thread.GetData( - Thread.GetNamedDataSlot("SharpRaven.Nancy.NancyContext")) as NancyContext; + Thread.GetNamedDataSlot(Configuration.Settings.NancyContextDataSlot)) as NancyContext; // get SentryRequest - ISentryRequest sentryRequest = Nancy.Data.SentryRequest.GetRequest(this.httpContext); + ISentryRequest sentryRequest = SharpRaven.Nancy.Data.SentryRequest.GetRequest(this.httpContext); // patch JsonPacket.Request with data on NancyContext packet.Request = sentryRequest; From 4590564d8d7e01e27f5d100bf91655038f6ea61b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 14 Nov 2014 12:35:42 +0100 Subject: [PATCH 007/171] Performed ReSharper code cleanup --- .../SharpRaven.Nancy/ApplicationStartup.cs | 49 ++++++++-- src/app/SharpRaven.Nancy/Configuration.cs | 91 ++++++++++--------- .../SharpRaven.Nancy/Data/SentryRequest.cs | 69 +++++++------- src/app/SharpRaven.Nancy/RavenClient.cs | 42 ++++++++- 4 files changed, 163 insertions(+), 88 deletions(-) diff --git a/src/app/SharpRaven.Nancy/ApplicationStartup.cs b/src/app/SharpRaven.Nancy/ApplicationStartup.cs index a8bff2b3..7b6f63b9 100644 --- a/src/app/SharpRaven.Nancy/ApplicationStartup.cs +++ b/src/app/SharpRaven.Nancy/ApplicationStartup.cs @@ -1,9 +1,39 @@ -using System; -using System.Configuration; -using Nancy.Bootstrapper; -using Nancy; +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; using System.Threading; +using Nancy; +using Nancy.Bootstrapper; + namespace SharpRaven.Nancy { public class ApplicationStartup : IApplicationStartup @@ -11,11 +41,12 @@ public class ApplicationStartup : IApplicationStartup public void Initialize(IPipelines pipelines) { var sharpRaven = new PipelineItem>( - Configuration.Settings.PipelineName.Value, (context, exception) => + Configuration.Settings.PipelineName.Value, + (context, exception) => { Thread.SetData( - Thread.GetNamedDataSlot(Configuration.Settings.NancyContextDataSlot), - context); + Thread.GetNamedDataSlot(Configuration.Settings.NancyContextDataSlot), + context); if (Configuration.Settings.CaptureExceptionOnError.Value) { @@ -30,6 +61,4 @@ public void Initialize(IPipelines pipelines) pipelines.OnError.AddItemToStartOfPipeline(sharpRaven); } } -} - - +} \ No newline at end of file diff --git a/src/app/SharpRaven.Nancy/Configuration.cs b/src/app/SharpRaven.Nancy/Configuration.cs index 0a1461a9..347d9d90 100644 --- a/src/app/SharpRaven.Nancy/Configuration.cs +++ b/src/app/SharpRaven.Nancy/Configuration.cs @@ -1,4 +1,34 @@ -using System; +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; using System.Configuration; namespace SharpRaven.Nancy @@ -7,57 +37,30 @@ public class Configuration : SharpRaven.Configuration { private const string pipelineNameKey = "pipelineName"; private const string captureExceptionOnErrorKey = "captureExceptionOnError"; + private static readonly Configuration settings = ConfigurationManager.GetSection("sharpRaven") as Configuration; public static Configuration Settings { - get - { - return settings; - } + get { return settings; } } public string NancyContextDataSlot { - get - { - return "SharpRaven.Nancy.NancyContext"; - } + get { return "SharpRaven.Nancy.NancyContext"; } } [ConfigurationProperty(pipelineNameKey, IsKey = true)] public PipelineNameElement PipelineName { - get - { - return (PipelineNameElement)base[pipelineNameKey]; - } - } - - public class PipelineNameElement : ConfigurationElement - { - [ConfigurationProperty("value", DefaultValue = "SharpRaven.Nancy")] - public String Value - { - get - { - return (string)this["value"]; - } - set - { - this["value"] = value; - } - } + get { return (PipelineNameElement) base[pipelineNameKey]; } } [ConfigurationProperty(captureExceptionOnErrorKey, IsKey = true)] public CaptureExceptionOnErrorElement CaptureExceptionOnError { - get - { - return (CaptureExceptionOnErrorElement)base[captureExceptionOnErrorKey]; - } + get { return (CaptureExceptionOnErrorElement) base[captureExceptionOnErrorKey]; } } public class CaptureExceptionOnErrorElement : ConfigurationElement @@ -65,15 +68,19 @@ public class CaptureExceptionOnErrorElement : ConfigurationElement [ConfigurationProperty("value", DefaultValue = "true")] public bool Value { - get - { - return (bool)this["value"]; - } - set - { - this["value"] = value; - } + get { return (bool) this["value"]; } + set { this["value"] = value; } + } + } + + public class PipelineNameElement : ConfigurationElement + { + [ConfigurationProperty("value", DefaultValue = "SharpRaven.Nancy")] + public String Value + { + get { return (string) this["value"]; } + set { this["value"] = value; } } } } -} +} \ No newline at end of file diff --git a/src/app/SharpRaven.Nancy/Data/SentryRequest.cs b/src/app/SharpRaven.Nancy/Data/SentryRequest.cs index b0c67295..149a7362 100644 --- a/src/app/SharpRaven.Nancy/Data/SentryRequest.cs +++ b/src/app/SharpRaven.Nancy/Data/SentryRequest.cs @@ -28,20 +28,19 @@ #endregion -using System; using System.Collections.Generic; -using System.Collections.Specialized; +using System.IO; using System.Linq; -using System.Reflection; -using System.Security.Principal; -using Newtonsoft.Json; using System.Text; -using System.Threading; -using System.IO; -using NancyIO = Nancy.IO; + using Nancy; + +using Newtonsoft.Json; + using SharpRaven.Data; +using NancyIO = Nancy.IO; + namespace SharpRaven.Nancy.Data { /// @@ -51,11 +50,6 @@ public class SentryRequest : ISentryRequest { private readonly NancyContext httpContext; - [JsonIgnore] - private bool HasHttpContext - { - get { return this.httpContext != null; } - } internal SentryRequest(NancyContext httpContext) { @@ -67,8 +61,8 @@ internal SentryRequest(NancyContext httpContext) } // Url and Method - this.Url = this.httpContext.Request.Url.ToString(); - this.Method = this.httpContext.Request.Method; + Url = this.httpContext.Request.Url.ToString(); + Method = this.httpContext.Request.Method; // Data NancyIO.RequestStream requestStream = this.httpContext.Request.Body; @@ -81,7 +75,7 @@ internal SentryRequest(NancyContext httpContext) StreamReader reader = new StreamReader(requestStream); // read data - this.Data = reader.ReadToEnd(); + Data = reader.ReadToEnd(); } // QueryString @@ -91,28 +85,37 @@ internal SentryRequest(NancyContext httpContext) qs += item + "=" + this.httpContext.Request.Query[item] + "&"; } - this.QueryString = qs.TrimEnd(new char[] { '&' }); + QueryString = qs.TrimEnd(new char[] { '&' }); // Cookies - this.Cookies = this.httpContext.Request.Cookies; + Cookies = this.httpContext.Request.Cookies; // Headers - this.Headers = this.httpContext.Request.Headers - .Select(s => new - { - Key = s.Key, - Value = s.Value.Aggregate(new StringBuilder(), (stringBuilder, argument) => - { - stringBuilder.Append(argument + " "); - - return stringBuilder; - }) - .ToString() - .TrimEnd(new char[] { ' ' }) - }) - .ToDictionary(k => k.Key, v => v.Value); + Headers = this.httpContext.Request.Headers + .Select(s => new + { + Key = s.Key, + Value = s.Value.Aggregate(new StringBuilder(), + (stringBuilder, argument) => + { + stringBuilder.Append(argument + " "); + + return stringBuilder; + }) + .ToString() + .TrimEnd(new char[] { ' ' }) + }) + .ToDictionary(k => k.Key, v => v.Value); + } + + + [JsonIgnore] + private bool HasHttpContext + { + get { return this.httpContext != null; } } + /// /// Gets or sets the cookies. /// @@ -177,6 +180,7 @@ internal SentryRequest(NancyContext httpContext) [JsonProperty(PropertyName = "url", NullValueHandling = NullValueHandling.Ignore)] public string Url { get; set; } + /// /// Gets the user. /// @@ -196,6 +200,7 @@ public SentryUser GetUser() }; } + /// /// Gets the request. /// diff --git a/src/app/SharpRaven.Nancy/RavenClient.cs b/src/app/SharpRaven.Nancy/RavenClient.cs index 58e7842c..68093f8d 100644 --- a/src/app/SharpRaven.Nancy/RavenClient.cs +++ b/src/app/SharpRaven.Nancy/RavenClient.cs @@ -1,7 +1,39 @@ -using Nancy; -using SharpRaven.Data; +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + using System.Threading; +using Nancy; + +using SharpRaven.Data; + namespace SharpRaven.Nancy { /// @@ -11,6 +43,7 @@ public class RavenClient : SharpRaven.RavenClient { private NancyContext httpContext; + /// /// Initializes a new instance of the class. Sentry /// Data Source Name will be read from sharpRaven section in your app.config or @@ -24,6 +57,7 @@ public RavenClient(NancyContext httpContext = null, IJsonPacketFactory jsonPacke this.httpContext = httpContext; } + /// /// Sends the specified packet to Sentry. /// @@ -39,7 +73,7 @@ protected override string Send(JsonPacket packet, Dsn dsn) Thread.GetNamedDataSlot(Configuration.Settings.NancyContextDataSlot)) as NancyContext; // get SentryRequest - ISentryRequest sentryRequest = SharpRaven.Nancy.Data.SentryRequest.GetRequest(this.httpContext); + ISentryRequest sentryRequest = Data.SentryRequest.GetRequest(this.httpContext); // patch JsonPacket.Request with data on NancyContext packet.Request = sentryRequest; @@ -50,4 +84,4 @@ protected override string Send(JsonPacket packet, Dsn dsn) return base.Send(packet, dsn); } } -} +} \ No newline at end of file From e01f6fea660cbd81347a4e732cb1ebebb9a5abf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 14 Nov 2014 12:37:30 +0100 Subject: [PATCH 008/171] Removed unused references --- src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj index 11c18751..b42a6d84 100644 --- a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj +++ b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj @@ -60,11 +60,7 @@ - - - - From 0fd8e66fc799f8ce4e2fdee925abb112548099d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 14 Nov 2014 12:39:03 +0100 Subject: [PATCH 009/171] Only do simple argument wrap --- src/SharpRaven.sln.DotSettings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SharpRaven.sln.DotSettings b/src/SharpRaven.sln.DotSettings index 77df1b30..c9fe89ed 100644 --- a/src/SharpRaven.sln.DotSettings +++ b/src/SharpRaven.sln.DotSettings @@ -32,7 +32,7 @@ False False True - CHOP_IF_LONG + WRAP_IF_LONG WRAP_IF_LONG CHOP_IF_LONG CHOP_IF_LONG From d74b7da2e41011a2ca2b12d65761d6d6866d9b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 14 Nov 2014 12:39:54 +0100 Subject: [PATCH 010/171] Reformatted ApplicationStartup a bit by extracting to variables and such. --- .../SharpRaven.Nancy/ApplicationStartup.cs | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/app/SharpRaven.Nancy/ApplicationStartup.cs b/src/app/SharpRaven.Nancy/ApplicationStartup.cs index 7b6f63b9..58523b90 100644 --- a/src/app/SharpRaven.Nancy/ApplicationStartup.cs +++ b/src/app/SharpRaven.Nancy/ApplicationStartup.cs @@ -40,23 +40,21 @@ public class ApplicationStartup : IApplicationStartup { public void Initialize(IPipelines pipelines) { - var sharpRaven = new PipelineItem>( - Configuration.Settings.PipelineName.Value, - (context, exception) => + var value = Configuration.Settings.PipelineName.Value; + var sharpRaven = new PipelineItem>(value, (context, exception) => + { + var nancyContextDataSlot = Configuration.Settings.NancyContextDataSlot; + var localDataStoreSlot = Thread.GetNamedDataSlot(nancyContextDataSlot); + Thread.SetData(localDataStoreSlot, context); + + if (Configuration.Settings.CaptureExceptionOnError.Value) { - Thread.SetData( - Thread.GetNamedDataSlot(Configuration.Settings.NancyContextDataSlot), - context); + IRavenClient client = new RavenClient(context); + client.CaptureException(exception); + } - if (Configuration.Settings.CaptureExceptionOnError.Value) - { - IRavenClient client = new RavenClient(context); - - client.CaptureException(exception); - } - - return null; - }); + return null; + }); pipelines.OnError.AddItemToStartOfPipeline(sharpRaven); } From 2416efb30dd7cbd5122260236cf8a60563dfd0d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 14 Nov 2014 12:40:57 +0100 Subject: [PATCH 011/171] Constants should be upper camel cased. --- src/app/SharpRaven.Nancy/Configuration.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/app/SharpRaven.Nancy/Configuration.cs b/src/app/SharpRaven.Nancy/Configuration.cs index 347d9d90..88db5850 100644 --- a/src/app/SharpRaven.Nancy/Configuration.cs +++ b/src/app/SharpRaven.Nancy/Configuration.cs @@ -35,8 +35,8 @@ namespace SharpRaven.Nancy { public class Configuration : SharpRaven.Configuration { - private const string pipelineNameKey = "pipelineName"; - private const string captureExceptionOnErrorKey = "captureExceptionOnError"; + private const string PipelineNameKey = "pipelineName"; + private const string CaptureExceptionOnErrorKey = "captureExceptionOnError"; private static readonly Configuration settings = ConfigurationManager.GetSection("sharpRaven") as Configuration; @@ -51,16 +51,16 @@ public string NancyContextDataSlot get { return "SharpRaven.Nancy.NancyContext"; } } - [ConfigurationProperty(pipelineNameKey, IsKey = true)] + [ConfigurationProperty(PipelineNameKey, IsKey = true)] public PipelineNameElement PipelineName { - get { return (PipelineNameElement) base[pipelineNameKey]; } + get { return (PipelineNameElement) base[PipelineNameKey]; } } - [ConfigurationProperty(captureExceptionOnErrorKey, IsKey = true)] + [ConfigurationProperty(CaptureExceptionOnErrorKey, IsKey = true)] public CaptureExceptionOnErrorElement CaptureExceptionOnError { - get { return (CaptureExceptionOnErrorElement) base[captureExceptionOnErrorKey]; } + get { return (CaptureExceptionOnErrorElement) base[CaptureExceptionOnErrorKey]; } } public class CaptureExceptionOnErrorElement : ConfigurationElement From 2964580bed838c05849a05acbcffb1f19edcda01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 14 Nov 2014 12:45:05 +0100 Subject: [PATCH 012/171] ReSharper cleanup and documentation of the Configuration class. --- src/app/SharpRaven/Configuration.cs | 80 +++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 17 deletions(-) diff --git a/src/app/SharpRaven/Configuration.cs b/src/app/SharpRaven/Configuration.cs index 0de745ef..7f1dda48 100644 --- a/src/app/SharpRaven/Configuration.cs +++ b/src/app/SharpRaven/Configuration.cs @@ -1,42 +1,88 @@ -using System; +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; using System.Configuration; namespace SharpRaven { + /// + /// SharpRaven configuration class. + /// public class Configuration : ConfigurationSection { - private const string dsnKey = "dsn"; + private const string DsnKey = "dsn"; + private static readonly Configuration settings = ConfigurationManager.GetSection("sharpRaven") as Configuration; + /// + /// Gets the <sharpRaven/> configuration element. + /// + /// + /// The the <sharpRaven/> configuration element. + /// public static Configuration Settings { - get - { - return settings; - } + get { return settings; } } - [ConfigurationProperty(dsnKey, IsKey = true)] + /// + /// Gets the value of the <dsn/> configuration element. + /// + /// + /// The value of the <dsn/> configuration element. + /// + [ConfigurationProperty(DsnKey, IsKey = true)] public DsnElement Dsn { - get { return (DsnElement)base[dsnKey]; } + get { return (DsnElement) base[DsnKey]; } } + /// + /// The <dsn/> configuration element. + /// public class DsnElement : ConfigurationElement { + /// + /// Gets the value of the <dsn/> configuration element. + /// + /// + /// The value of the <dsn/> configuration element. + /// [ConfigurationProperty("value")] public String Value { - get - { - return (String)this["value"]; - } - set - { - this["value"] = value; - } + get { return (String) this["value"]; } + set { this["value"] = value; } } } } -} +} \ No newline at end of file From 17b2f9dbea622620b6f4a3b5910597f795c0df63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 14 Nov 2014 12:45:11 +0100 Subject: [PATCH 013/171] Added `new` to the Configuration.Setings property. --- src/app/SharpRaven.Nancy/Configuration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/SharpRaven.Nancy/Configuration.cs b/src/app/SharpRaven.Nancy/Configuration.cs index 88db5850..917b1ffc 100644 --- a/src/app/SharpRaven.Nancy/Configuration.cs +++ b/src/app/SharpRaven.Nancy/Configuration.cs @@ -41,7 +41,7 @@ public class Configuration : SharpRaven.Configuration private static readonly Configuration settings = ConfigurationManager.GetSection("sharpRaven") as Configuration; - public static Configuration Settings + public new static Configuration Settings { get { return settings; } } From 25a33e404ddfe667b7b11e1126fcd6c048a9a185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 14 Nov 2014 12:46:14 +0100 Subject: [PATCH 014/171] Turned on XML documentation for SharpRaven.Nancy --- src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj index b42a6d84..fe1c437e 100644 --- a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj +++ b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj @@ -21,6 +21,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + bin\Debug\net40\SharpRaven.Nancy.xml true @@ -30,6 +31,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + bin\Debug\net45\SharpRaven.Nancy.xml bin\Release\net40\ @@ -39,6 +41,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + bin\Release\net40\SharpRaven.Nancy.xml bin\Release\net45\ @@ -48,6 +51,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + bin\Release\net45\SharpRaven.Nancy.xml From 383975fc5cc5b4e14004da01cd86c97c2f4948b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 14 Nov 2014 12:47:55 +0100 Subject: [PATCH 015/171] Clarified Configuration documentation --- src/app/SharpRaven/Configuration.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/SharpRaven/Configuration.cs b/src/app/SharpRaven/Configuration.cs index 7f1dda48..74d00ba6 100644 --- a/src/app/SharpRaven/Configuration.cs +++ b/src/app/SharpRaven/Configuration.cs @@ -55,10 +55,10 @@ public static Configuration Settings } /// - /// Gets the value of the <dsn/> configuration element. + /// Gets the <dsn/> configuration element. /// /// - /// The value of the <dsn/> configuration element. + /// The <dsn/> configuration element. /// [ConfigurationProperty(DsnKey, IsKey = true)] public DsnElement Dsn From e8b70744e9f3c7975a245281d836e3f067f70539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 14 Nov 2014 12:50:17 +0100 Subject: [PATCH 016/171] Added documentation to the Configuration class --- src/app/SharpRaven.Nancy/Configuration.cs | 45 +++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/app/SharpRaven.Nancy/Configuration.cs b/src/app/SharpRaven.Nancy/Configuration.cs index 917b1ffc..4e59fb6f 100644 --- a/src/app/SharpRaven.Nancy/Configuration.cs +++ b/src/app/SharpRaven.Nancy/Configuration.cs @@ -33,6 +33,9 @@ namespace SharpRaven.Nancy { + /// + /// Nancy-specific configuration for SharpRaven. + /// public class Configuration : SharpRaven.Configuration { private const string PipelineNameKey = "pipelineName"; @@ -41,30 +44,63 @@ public class Configuration : SharpRaven.Configuration private static readonly Configuration settings = ConfigurationManager.GetSection("sharpRaven") as Configuration; + /// + /// Gets the <sharpRaven/> configuration element. + /// + /// + /// The the <sharpRaven/> configuration element. + /// public new static Configuration Settings { get { return settings; } } + /// + /// Gets the nancy context data slot. + /// + /// + /// The nancy context data slot. + /// public string NancyContextDataSlot { get { return "SharpRaven.Nancy.NancyContext"; } } + /// + /// Gets the <pipelineName /> configuration element. + /// + /// + /// The <pipelineName /> configuration element. + /// [ConfigurationProperty(PipelineNameKey, IsKey = true)] public PipelineNameElement PipelineName { get { return (PipelineNameElement) base[PipelineNameKey]; } } + /// + /// Gets the <captureExceptionOnError /> configuration element. + /// + /// + /// The <captureExceptionOnError /> configuration element. + /// [ConfigurationProperty(CaptureExceptionOnErrorKey, IsKey = true)] public CaptureExceptionOnErrorElement CaptureExceptionOnError { get { return (CaptureExceptionOnErrorElement) base[CaptureExceptionOnErrorKey]; } } + /// + /// The <captureExceptionOnError /> configuration element. + /// public class CaptureExceptionOnErrorElement : ConfigurationElement { + /// + /// Gets or sets the value of the the <captureExceptionOnError /> configuration element. + /// + /// + /// true if exceptions should be captured by SharpRaven; otherwise, false. + /// [ConfigurationProperty("value", DefaultValue = "true")] public bool Value { @@ -73,8 +109,17 @@ public bool Value } } + /// + /// The <pipelineName /> configuration element. + /// public class PipelineNameElement : ConfigurationElement { + /// + /// Gets or sets the value of the <pipelineName /> configuration element. + /// + /// + /// The value of the the <pipelineName /> configuration element. + /// [ConfigurationProperty("value", DefaultValue = "SharpRaven.Nancy")] public String Value { From c0dbaaa0d3848ebb7538b36b5a0adeee974ce072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 14 Nov 2014 12:51:25 +0100 Subject: [PATCH 017/171] Added documentation to the ApplicationStartup class --- src/app/SharpRaven.Nancy/ApplicationStartup.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/app/SharpRaven.Nancy/ApplicationStartup.cs b/src/app/SharpRaven.Nancy/ApplicationStartup.cs index 58523b90..659c944a 100644 --- a/src/app/SharpRaven.Nancy/ApplicationStartup.cs +++ b/src/app/SharpRaven.Nancy/ApplicationStartup.cs @@ -36,8 +36,16 @@ namespace SharpRaven.Nancy { + /// + /// SharpRaven's implementation. + /// Used to register exception handling to the start of the error handling pipeline. + /// public class ApplicationStartup : IApplicationStartup { + /// + /// Perform any initialisation tasks + /// + /// Application pipelines public void Initialize(IPipelines pipelines) { var value = Configuration.Settings.PipelineName.Value; From 47e43a550d427088c26ab37baef2c0ea0e8c9c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 14 Nov 2014 12:55:39 +0100 Subject: [PATCH 018/171] Extracted a couple of variables for clarity --- src/app/SharpRaven.Nancy/RavenClient.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/SharpRaven.Nancy/RavenClient.cs b/src/app/SharpRaven.Nancy/RavenClient.cs index 68093f8d..faf8b3cc 100644 --- a/src/app/SharpRaven.Nancy/RavenClient.cs +++ b/src/app/SharpRaven.Nancy/RavenClient.cs @@ -69,8 +69,9 @@ public RavenClient(NancyContext httpContext = null, IJsonPacketFactory jsonPacke protected override string Send(JsonPacket packet, Dsn dsn) { // looking for NancyContext - this.httpContext = this.httpContext ?? Thread.GetData( - Thread.GetNamedDataSlot(Configuration.Settings.NancyContextDataSlot)) as NancyContext; + var nancyContextDataSlot = Configuration.Settings.NancyContextDataSlot; + var localDataStoreSlot = Thread.GetNamedDataSlot(nancyContextDataSlot); + this.httpContext = this.httpContext ?? Thread.GetData(localDataStoreSlot) as NancyContext; // get SentryRequest ISentryRequest sentryRequest = Data.SentryRequest.GetRequest(this.httpContext); From 6de1e40140b32e1342f80ca69e73e35363f3e090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 14 Nov 2014 12:56:54 +0100 Subject: [PATCH 019/171] Added GitVersionTask to SharpRaven.Nancy --- src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj | 8 ++++++++ src/app/SharpRaven.Nancy/packages.config | 1 + 2 files changed, 9 insertions(+) diff --git a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj index fe1c437e..413618b3 100644 --- a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj +++ b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj @@ -12,6 +12,7 @@ v4.5 512 + 7a004730 true @@ -83,6 +84,13 @@ + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/src/tests/SharpRaven.Nancy.WebTest/default.html b/src/tests/SharpRaven.Nancy.WebTest/default.html new file mode 100644 index 00000000..f31cbae5 --- /dev/null +++ b/src/tests/SharpRaven.Nancy.WebTest/default.html @@ -0,0 +1,12 @@ + + + + Capture exception + + +

Capture exception

+
+ +
+ + \ No newline at end of file diff --git a/src/tests/SharpRaven.Nancy.WebTest/error.html b/src/tests/SharpRaven.Nancy.WebTest/error.html new file mode 100644 index 00000000..cfd7b066 --- /dev/null +++ b/src/tests/SharpRaven.Nancy.WebTest/error.html @@ -0,0 +1,10 @@ + + + + Exception captured! + + +

Exception captured!

+

Exception id: @Model.ExceptionId

+ + \ No newline at end of file diff --git a/src/tests/SharpRaven.Nancy.WebTest/packages.config b/src/tests/SharpRaven.Nancy.WebTest/packages.config new file mode 100644 index 00000000..4ffc7571 --- /dev/null +++ b/src/tests/SharpRaven.Nancy.WebTest/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file From fe3df30cabbb4c23f75cefd253e374f6c478bed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Mon, 24 Nov 2014 15:04:29 +0100 Subject: [PATCH 023/171] Removed unused references --- .../SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj index 991231a4..02631edc 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj +++ b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj @@ -62,11 +62,6 @@
- - - - - From 9ef115e49bc621690e12a835784fc325dea5ea6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Mon, 24 Nov 2014 15:13:03 +0100 Subject: [PATCH 024/171] Don't force simple anonymous methods to single-line --- src/SharpRaven.sln.DotSettings | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SharpRaven.sln.DotSettings b/src/SharpRaven.sln.DotSettings index c9fe89ed..0260b856 100644 --- a/src/SharpRaven.sln.DotSettings +++ b/src/SharpRaven.sln.DotSettings @@ -26,6 +26,7 @@ False False False + False USE_FOR_VARIABLES_IN_THIS_CLASS LINE_BREAK True From 0d289cd0bcf39e370796bf9d8689349c7df29d82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Mon, 24 Nov 2014 15:13:26 +0100 Subject: [PATCH 025/171] Added SharpRaven.Nancy.WebTest package repository --- src/packages/repositories.config | 1 + 1 file changed, 1 insertion(+) diff --git a/src/packages/repositories.config b/src/packages/repositories.config index fdb1f0c0..cfabae81 100644 --- a/src/packages/repositories.config +++ b/src/packages/repositories.config @@ -2,5 +2,6 @@ + \ No newline at end of file From 0e0662e7d7518d30898190cff6631a0e30bef709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Mon, 24 Nov 2014 15:22:23 +0100 Subject: [PATCH 026/171] Added TODO: We should retrieve an IRavenClient instance from the application container. --- src/app/SharpRaven.Nancy/ApplicationStartup.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/SharpRaven.Nancy/ApplicationStartup.cs b/src/app/SharpRaven.Nancy/ApplicationStartup.cs index 659c944a..fb05a34f 100644 --- a/src/app/SharpRaven.Nancy/ApplicationStartup.cs +++ b/src/app/SharpRaven.Nancy/ApplicationStartup.cs @@ -57,6 +57,7 @@ public void Initialize(IPipelines pipelines) if (Configuration.Settings.CaptureExceptionOnError.Value) { + // TODO: We should retrieve an IRavenClient instance from the application container. @asbjornu IRavenClient client = new RavenClient(context); client.CaptureException(exception); } From ddd835b1612c63d145081dd6a466cb781104de3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Mon, 24 Nov 2014 15:22:37 +0100 Subject: [PATCH 027/171] R# and simplification --- src/app/SharpRaven.Nancy/ApplicationStartup.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/SharpRaven.Nancy/ApplicationStartup.cs b/src/app/SharpRaven.Nancy/ApplicationStartup.cs index fb05a34f..44af55c1 100644 --- a/src/app/SharpRaven.Nancy/ApplicationStartup.cs +++ b/src/app/SharpRaven.Nancy/ApplicationStartup.cs @@ -36,6 +36,8 @@ namespace SharpRaven.Nancy { + using PipelineItem = PipelineItem>; + /// /// SharpRaven's implementation. /// Used to register exception handling to the start of the error handling pipeline. @@ -49,7 +51,7 @@ public class ApplicationStartup : IApplicationStartup public void Initialize(IPipelines pipelines) { var value = Configuration.Settings.PipelineName.Value; - var sharpRaven = new PipelineItem>(value, (context, exception) => + var sharpRaven = new PipelineItem(value, (context, exception) => { var nancyContextDataSlot = Configuration.Settings.NancyContextDataSlot; var localDataStoreSlot = Thread.GetNamedDataSlot(nancyContextDataSlot); @@ -58,7 +60,7 @@ public void Initialize(IPipelines pipelines) if (Configuration.Settings.CaptureExceptionOnError.Value) { // TODO: We should retrieve an IRavenClient instance from the application container. @asbjornu - IRavenClient client = new RavenClient(context); + var client = new RavenClient(context); client.CaptureException(exception); } From 3179cf6adc0fe9efa1335db07d2def59dba3301e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Mon, 24 Nov 2014 15:30:24 +0100 Subject: [PATCH 028/171] Added Nancy.Testing, NUnit and NSubstitute to SharpRaven.Nancy.WebTests --- .../SharpRaven.Nancy.WebTest.csproj | 12 ++++++++++++ src/tests/SharpRaven.Nancy.WebTest/packages.config | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj index 02631edc..0757bce2 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj +++ b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj @@ -54,12 +54,24 @@ true + + ..\..\packages\CsQuery.1.3.3\lib\net40\CsQuery.dll + ..\..\packages\Nancy.0.23.2\lib\net40\Nancy.dll ..\..\packages\Nancy.Hosting.Self.0.23.2\lib\net40\Nancy.Hosting.Self.dll + + ..\..\packages\Nancy.Testing.0.23.2\lib\net40\Nancy.Testing.dll + + + ..\..\packages\NSubstitute.1.8.0.0\lib\net45\NSubstitute.dll + + + ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + diff --git a/src/tests/SharpRaven.Nancy.WebTest/packages.config b/src/tests/SharpRaven.Nancy.WebTest/packages.config index 4ffc7571..925b17f5 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/packages.config +++ b/src/tests/SharpRaven.Nancy.WebTest/packages.config @@ -1,5 +1,9 @@  + + + + \ No newline at end of file From 8c7e0d4c568ec47394c5555b2d9a87efbb4c6dad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Mon, 24 Nov 2014 15:31:58 +0100 Subject: [PATCH 029/171] Rejigged the DefaultModule to throw exception so the ApplicationStartup pipeline registration can act upon it. --- .../SharpRaven.Nancy.WebTest/DefaultModule.cs | 76 +++++++++++-------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/src/tests/SharpRaven.Nancy.WebTest/DefaultModule.cs b/src/tests/SharpRaven.Nancy.WebTest/DefaultModule.cs index d06dbde8..a00b980e 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/DefaultModule.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/DefaultModule.cs @@ -1,15 +1,51 @@ -using Nancy; -using Nancy.Hosting.Self; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using Nancy; namespace SharpRaven.Nancy.WebTest { public class DefaultModule : NancyModule { + public DefaultModule() + { + Get["/"] = _ => View["default.html"]; + + Post["/"] = _ => + { + DivideByZero(); + return View["error.html"]; + }; + } + + private static void DivideByZero(int stackFrames = 10) { if (stackFrames == 0) @@ -22,29 +58,5 @@ private static void DivideByZero(int stackFrames = 10) DivideByZero(--stackFrames); } } - - public DefaultModule() - { - Get["/"] = _ => { - return View["default.html"]; - }; - - Post["/"] = _ => - { - string exceptionId = String.Empty; - - try - { - DivideByZero(); - } - catch (Exception ex) - { - IRavenClient ravenClient = new RavenClient(this.Context); - exceptionId = ravenClient.CaptureException(ex); - } - - return View["error.html", new { ExceptionId = exceptionId }]; - }; - } } -} +} \ No newline at end of file From a8308ac3afe6438c85f726900f5cf531aa7abbc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Mon, 24 Nov 2014 15:32:33 +0100 Subject: [PATCH 030/171] Added NancyTest to see that IRaveClient is invoked when an exception occurs. --- .../SharpRaven.Nancy.WebTest/NancyTests.cs | 70 +++++++++++++++++++ .../SharpRaven.Nancy.WebTest.csproj | 1 + 2 files changed, 71 insertions(+) create mode 100644 src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs diff --git a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs new file mode 100644 index 00000000..c893fa47 --- /dev/null +++ b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs @@ -0,0 +1,70 @@ +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; + +using Nancy.Testing; + +using NSubstitute; + +using NUnit.Framework; + +namespace SharpRaven.Nancy.WebTest +{ + [TestFixture] + public class NancyTests + { + [Test] + public void Post_InvokesRavenClient() + { + var ravenClient = Substitute.For(); + + var browser = new Browser(c => + { + c.Module(); + + c.ApplicationStartup((container, pipelines) => + { + container.Register(ravenClient); + container.AutoRegister(new[] { typeof(ApplicationStartup).Assembly }, type => true); + }); + }); + + + TestDelegate throwing = () => browser.Post("/"); + + var exception = Assert.Throws(throwing); + Assert.That(exception.InnerException, Is.Not.Null); + Assert.That(exception.InnerException.Message, Is.StringContaining("Oh noes!")); + + ravenClient.Received(1).CaptureException(Arg.Any()); + } + } +} \ No newline at end of file diff --git a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj index 0757bce2..46524a75 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj +++ b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj @@ -77,6 +77,7 @@ + From 37057bf283b8a81f04bb3cb057831f40a50ec85d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Mon, 24 Nov 2014 15:50:29 +0100 Subject: [PATCH 031/171] Replaced IApplicationStartup with an IRequestStartup implementation so we get a fresh IRavenClient instance from the IoC container on every request. Solves the TODO added in 0e0662e7d7518d30898190cff6631a0e30bef709 and makes the test pass. --- .../SharpRaven.Nancy/ApplicationStartup.cs | 34 ++++++++++++++----- .../SharpRaven.Nancy.WebTest/NancyTests.cs | 2 +- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/app/SharpRaven.Nancy/ApplicationStartup.cs b/src/app/SharpRaven.Nancy/ApplicationStartup.cs index 44af55c1..54948f76 100644 --- a/src/app/SharpRaven.Nancy/ApplicationStartup.cs +++ b/src/app/SharpRaven.Nancy/ApplicationStartup.cs @@ -39,29 +39,45 @@ namespace SharpRaven.Nancy using PipelineItem = PipelineItem>; /// - /// SharpRaven's implementation. + /// SharpRaven's implementation. /// Used to register exception handling to the start of the error handling pipeline. /// - public class ApplicationStartup : IApplicationStartup + public class SentryRequestStartup : IRequestStartup { + private readonly IRavenClient ravenClient; + + + /// + /// Initializes a new instance of the class. + /// + /// The raven client. + /// ravenClient + public SentryRequestStartup(IRavenClient ravenClient) + { + if (ravenClient == null) + throw new ArgumentNullException("ravenClient"); + + this.ravenClient = ravenClient; + } + + /// /// Perform any initialisation tasks /// /// Application pipelines - public void Initialize(IPipelines pipelines) + /// The current context + public void Initialize(IPipelines pipelines, NancyContext context) { - var value = Configuration.Settings.PipelineName.Value; - var sharpRaven = new PipelineItem(value, (context, exception) => + var name = Configuration.Settings.PipelineName.Value; + var sharpRaven = new PipelineItem(name, (nancyContext, exception) => { var nancyContextDataSlot = Configuration.Settings.NancyContextDataSlot; var localDataStoreSlot = Thread.GetNamedDataSlot(nancyContextDataSlot); - Thread.SetData(localDataStoreSlot, context); + Thread.SetData(localDataStoreSlot, nancyContext); if (Configuration.Settings.CaptureExceptionOnError.Value) { - // TODO: We should retrieve an IRavenClient instance from the application container. @asbjornu - var client = new RavenClient(context); - client.CaptureException(exception); + this.ravenClient.CaptureException(exception); } return null; diff --git a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs index c893fa47..91f5fba2 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs @@ -53,7 +53,7 @@ public void Post_InvokesRavenClient() c.ApplicationStartup((container, pipelines) => { container.Register(ravenClient); - container.AutoRegister(new[] { typeof(ApplicationStartup).Assembly }, type => true); + container.AutoRegister(new[] { typeof(SentryRequestStartup).Assembly }, type => true); }); }); From e8264a73fd83d7bbb33891dc9ae1526a5ed77dc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Mon, 24 Nov 2014 15:57:49 +0100 Subject: [PATCH 032/171] Made the NSubstitute assert specifically check for the thrown DivideByZeroException instead of any odd exception. --- src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs index 91f5fba2..6e676794 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs @@ -56,15 +56,18 @@ public void Post_InvokesRavenClient() container.AutoRegister(new[] { typeof(SentryRequestStartup).Assembly }, type => true); }); }); - - + TestDelegate throwing = () => browser.Post("/"); var exception = Assert.Throws(throwing); Assert.That(exception.InnerException, Is.Not.Null); - Assert.That(exception.InnerException.Message, Is.StringContaining("Oh noes!")); + + var divideByZeroException = exception.InnerException.InnerException; + + Assert.That(divideByZeroException, Is.Not.Null); + Assert.That(divideByZeroException, Is.TypeOf()); - ravenClient.Received(1).CaptureException(Arg.Any()); + ravenClient.Received(1).CaptureException(divideByZeroException); } } } \ No newline at end of file From 9841f33c6b95ba2718b44f74f598bf49954b46df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Mon, 24 Nov 2014 15:58:26 +0100 Subject: [PATCH 033/171] Renamed ApplicationStartup.cs to SentryRequestStartup.cs --- .../{ApplicationStartup.cs => SentryRequestStartup.cs} | 0 src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/app/SharpRaven.Nancy/{ApplicationStartup.cs => SentryRequestStartup.cs} (100%) diff --git a/src/app/SharpRaven.Nancy/ApplicationStartup.cs b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs similarity index 100% rename from src/app/SharpRaven.Nancy/ApplicationStartup.cs rename to src/app/SharpRaven.Nancy/SentryRequestStartup.cs diff --git a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj index 413618b3..1d57207a 100644 --- a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj +++ b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj @@ -68,7 +68,7 @@ - + From a898417e5c33f5a475732d4fce6db493b52bcc1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Mon, 24 Nov 2014 16:01:48 +0100 Subject: [PATCH 034/171] Added documentation to ISentryRequest --- src/app/SharpRaven/Data/ISentryRequest.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/app/SharpRaven/Data/ISentryRequest.cs b/src/app/SharpRaven/Data/ISentryRequest.cs index 0631675a..06874068 100644 --- a/src/app/SharpRaven/Data/ISentryRequest.cs +++ b/src/app/SharpRaven/Data/ISentryRequest.cs @@ -33,6 +33,9 @@ namespace SharpRaven.Data { + /// + /// Interface for the request object. + /// public interface ISentryRequest { /// From 26ce902c0bef8f5f7a2cfa9a2c9a65df3a3e351e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Mon, 24 Nov 2014 16:51:55 +0100 Subject: [PATCH 035/171] No need to explicitly auto-register; Nancy does this itself. --- src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs index 6e676794..fc37e69a 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs @@ -49,19 +49,14 @@ public void Post_InvokesRavenClient() var browser = new Browser(c => { c.Module(); - - c.ApplicationStartup((container, pipelines) => - { - container.Register(ravenClient); - container.AutoRegister(new[] { typeof(SentryRequestStartup).Assembly }, type => true); - }); + c.ApplicationStartup((container, pipelines) => container.Register(ravenClient)); }); - + TestDelegate throwing = () => browser.Post("/"); - + var exception = Assert.Throws(throwing); Assert.That(exception.InnerException, Is.Not.Null); - + var divideByZeroException = exception.InnerException.InnerException; Assert.That(divideByZeroException, Is.Not.Null); From b7412d0490a6484894adb7a427185b3ca253a1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 09:19:53 +0100 Subject: [PATCH 036/171] R# --- src/app/SharpRaven/Data/JsonPacket.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/SharpRaven/Data/JsonPacket.cs b/src/app/SharpRaven/Data/JsonPacket.cs index f1883514..fe98b21d 100644 --- a/src/app/SharpRaven/Data/JsonPacket.cs +++ b/src/app/SharpRaven/Data/JsonPacket.cs @@ -30,7 +30,6 @@ using System; using System.Collections.Generic; -using System.Linq; using Newtonsoft.Json; From efbcc6486fb2b3873f812d0bdb4bf90d31b60d74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 09:21:08 +0100 Subject: [PATCH 037/171] Guard against null in the NancyContext.Request object, which it will be in a test. --- src/app/SharpRaven.Nancy/Data/SentryRequest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/SharpRaven.Nancy/Data/SentryRequest.cs b/src/app/SharpRaven.Nancy/Data/SentryRequest.cs index f56c9cb3..186733b8 100644 --- a/src/app/SharpRaven.Nancy/Data/SentryRequest.cs +++ b/src/app/SharpRaven.Nancy/Data/SentryRequest.cs @@ -59,7 +59,7 @@ internal SentryRequest(NancyContext httpContext) { this.httpContext = httpContext; - if (!HasHttpContext) + if (!HasHttpContext || this.httpContext.Request == null) { return; } @@ -209,7 +209,6 @@ public SentryUser GetUser() public static SentryRequest GetRequest(NancyContext httpContext) { var request = new SentryRequest(httpContext); - return request.HasHttpContext ? request : null; } } From 9e15d9f868750b31f073ccc04219e2921d36c5a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 12:40:26 +0100 Subject: [PATCH 038/171] Added Microsoft.CSharp and System.Configuration to the SharpRaven.Nancy.WebTest project --- .../SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj index 46524a75..ab35efc5 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj +++ b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj @@ -57,6 +57,7 @@ ..\..\packages\CsQuery.1.3.3\lib\net40\CsQuery.dll + ..\..\packages\Nancy.0.23.2\lib\net40\Nancy.dll @@ -73,6 +74,7 @@ ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + From 50adbfab5dd69c3971ef5b1d495d3b41005f4978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 12:41:20 +0100 Subject: [PATCH 039/171] Set the GUID returned from Sentry on NancyContext.Items and Exception.Data with a new Configuration key called 'SentryEventGuid'. --- src/app/SharpRaven.Nancy/Configuration.cs | 12 ++++++++++++ src/app/SharpRaven.Nancy/SentryRequestStartup.cs | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/app/SharpRaven.Nancy/Configuration.cs b/src/app/SharpRaven.Nancy/Configuration.cs index 4e59fb6f..35f879e3 100644 --- a/src/app/SharpRaven.Nancy/Configuration.cs +++ b/src/app/SharpRaven.Nancy/Configuration.cs @@ -66,6 +66,18 @@ public string NancyContextDataSlot get { return "SharpRaven.Nancy.NancyContext"; } } + + /// + /// Gets the key for the GUID returned from Sentry after a successfully logged exception. + /// + /// + /// The key for the GUID returned from Sentry after a successfully logged exception. + /// + public string SentryEventGuid + { + get { return "SharpRaven.Nancy.SentryEventGuid"; } + } + /// /// Gets the <pipelineName /> configuration element. /// diff --git a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs index 54948f76..72ecf599 100644 --- a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs +++ b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs @@ -77,7 +77,13 @@ public void Initialize(IPipelines pipelines, NancyContext context) if (Configuration.Settings.CaptureExceptionOnError.Value) { - this.ravenClient.CaptureException(exception); + var guid = this.ravenClient.CaptureException(exception); + + if (guid != null) + { + context.Items.Add(Configuration.Settings.SentryEventGuid, guid); + exception.Data.Add(Configuration.Settings.SentryEventGuid, guid); + } } return null; From 7eadf4e5ae07718b064ea1ea328b7105e1058de3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 12:44:11 +0100 Subject: [PATCH 040/171] SentryRequest.Data should contain the POSTed form values dictionary, not the HTTP body string. --- src/app/SharpRaven.Nancy/Data/SentryRequest.cs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/app/SharpRaven.Nancy/Data/SentryRequest.cs b/src/app/SharpRaven.Nancy/Data/SentryRequest.cs index 186733b8..9c960130 100644 --- a/src/app/SharpRaven.Nancy/Data/SentryRequest.cs +++ b/src/app/SharpRaven.Nancy/Data/SentryRequest.cs @@ -67,20 +67,7 @@ internal SentryRequest(NancyContext httpContext) // Url and Method Url = this.httpContext.Request.Url.ToString(); Method = this.httpContext.Request.Method; - - // Data - NancyIO.RequestStream requestStream = this.httpContext.Request.Body; - - if (requestStream.Length > 0 && requestStream.CanRead && requestStream.CanSeek) - { - // seek the stream to begin - requestStream.Seek(0, SeekOrigin.Begin); - - StreamReader reader = new StreamReader(requestStream); - - // read data - Data = reader.ReadToEnd(); - } + Data = this.httpContext.Request.Form; // QueryString string qs = string.Empty; From 8d7f8de7fbfb2ae0428463f1abf8ece5263fc1d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 12:47:57 +0100 Subject: [PATCH 041/171] Renamed RavenClient.cs to NancyContextJsonPacketFactory.cs in preparation for a little architecture rejig. --- .../{RavenClient.cs => Data/NancyContextJsonPacketFactory.cs} | 0 src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/app/SharpRaven.Nancy/{RavenClient.cs => Data/NancyContextJsonPacketFactory.cs} (100%) diff --git a/src/app/SharpRaven.Nancy/RavenClient.cs b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs similarity index 100% rename from src/app/SharpRaven.Nancy/RavenClient.cs rename to src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs diff --git a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj index 1d57207a..4ef143b1 100644 --- a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj +++ b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj @@ -68,11 +68,11 @@ + - From 8a6451765eb9846e10ace8584c09b73020efd904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 12:49:52 +0100 Subject: [PATCH 042/171] Implemented the NancyContextJsonPacketFactory class with the same basic logic as the SentryClient it replaces --- .../Data/NancyContextJsonPacketFactory.cs | 52 +++++++------------ 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs index faf8b3cc..dc0fa296 100644 --- a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs +++ b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs @@ -34,55 +34,39 @@ using SharpRaven.Data; -namespace SharpRaven.Nancy +namespace SharpRaven.Nancy.Data { /// - /// The Raven Client, responsible for capturing exceptions and sending them to Sentry. + /// -based implementation of . /// - public class RavenClient : SharpRaven.RavenClient + public class NancyContextJsonPacketFactory : JsonPacketFactory { - private NancyContext httpContext; - - /// - /// Initializes a new instance of the class. Sentry - /// Data Source Name will be read from sharpRaven section in your app.config or - /// web.config. + /// Called when the has been created. Can be overridden to + /// adjust the values of the before it is sent to Sentry. /// - /// The optional that will be used to fill that will be sent to Sentry. - /// The optional factory that will be used to create the that will be sent to Sentry. - public RavenClient(NancyContext httpContext = null, IJsonPacketFactory jsonPacketFactory = null) - : base(new Dsn(Configuration.Settings.Dsn.Value), jsonPacketFactory) - { - this.httpContext = httpContext; - } - - - /// - /// Sends the specified packet to Sentry. - /// - /// The packet to send. - /// The Data Source Name in Sentry. + /// The json packet. /// - /// The of the successfully captured JSON packet, or null if it fails. + /// The . /// - protected override string Send(JsonPacket packet, Dsn dsn) + protected override JsonPacket OnCreate(JsonPacket jsonPacket) { - // looking for NancyContext var nancyContextDataSlot = Configuration.Settings.NancyContextDataSlot; var localDataStoreSlot = Thread.GetNamedDataSlot(nancyContextDataSlot); - this.httpContext = this.httpContext ?? Thread.GetData(localDataStoreSlot) as NancyContext; + var nancyContext = Thread.GetData(localDataStoreSlot) as NancyContext; + + if (nancyContext == null) + return jsonPacket; - // get SentryRequest - ISentryRequest sentryRequest = Data.SentryRequest.GetRequest(this.httpContext); + var sentryRequest = SentryRequest.GetRequest(nancyContext); - // patch JsonPacket.Request with data on NancyContext - packet.Request = sentryRequest; + if (sentryRequest == null) + return jsonPacket; - // patch JsonPacket.User with data on NancyContext - packet.User = sentryRequest.GetUser(); + jsonPacket.Request = sentryRequest; + jsonPacket.User = sentryRequest.GetUser(); - return base.Send(packet, dsn); + return jsonPacket; } } } \ No newline at end of file From 00b4e798f35f3b51c226e92e86cd843a98d1986f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 12:50:53 +0100 Subject: [PATCH 043/171] Added SentryRegistrations to provide default implementations of IRavenClient and IJsonPacketFactory. --- .../SharpRaven.Nancy/SentryRegistrations.cs | 94 +++++++++++++++++++ .../SharpRaven.Nancy/SharpRaven.Nancy.csproj | 3 + 2 files changed, 97 insertions(+) create mode 100644 src/app/SharpRaven.Nancy/SentryRegistrations.cs diff --git a/src/app/SharpRaven.Nancy/SentryRegistrations.cs b/src/app/SharpRaven.Nancy/SentryRegistrations.cs new file mode 100644 index 00000000..fae73973 --- /dev/null +++ b/src/app/SharpRaven.Nancy/SentryRegistrations.cs @@ -0,0 +1,94 @@ +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System.Collections.Generic; + +using Nancy; +using Nancy.Bootstrapper; + +using SharpRaven.Data; +using SharpRaven.Nancy.Data; + +namespace SharpRaven.Nancy +{ + /// + /// SharpRaven-specific implementation of to expose a different + /// default implementation of so + /// specific data can be sent to Sentry. + /// + public class SentryRegistrations : IRegistrations + { + /// + /// Gets the type registrations to register for this startup task + /// + public IEnumerable TypeRegistrations + { + get + { + return new[] + { + new TypeRegistration(typeof(IJsonPacketFactory), + typeof(NancyContextJsonPacketFactory), + Lifetime.Singleton), + // TODO: I'd like to register the RavenClient like this so it's more composable and IoC friendly, but I'm seemingly unable to override their registration, which makes testing impossible. @asbjornu + /*new TypeRegistration(typeof(IRavenClient), + typeof(RavenClient), + Lifetime.PerRequest),*/ + }; + } + } + + /// + /// Gets the collection registrations to register for this startup task + /// + public IEnumerable CollectionTypeRegistrations + { + get { return null; } + } + + /// + /// Gets the instance registrations to register for this startup task + /// + public IEnumerable InstanceRegistrations + { + get + { + return new[] + { + //new InstanceRegistration(typeof(Dsn), new Dsn(Configuration.Settings.Dsn.Value)), + // TODO: I don't like to register the concrete instance like this, see the above TODO. @asbjornu + new InstanceRegistration(typeof(IRavenClient), + new RavenClient(new Dsn(Configuration.Settings.Dsn.Value), + new NancyContextJsonPacketFactory())), + }; + } + } + } +} \ No newline at end of file diff --git a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj index 4ef143b1..d7be15a8 100644 --- a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj +++ b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj @@ -69,6 +69,9 @@ + + Code + From b902402d18453d490e7e65a400251f0c37db6b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 12:51:51 +0100 Subject: [PATCH 044/171] Added TestableRavenClient and rewrote the Nancy test so it tests every custom moving part of the Nancy bootstrapping. --- .../SharpRaven.Nancy.WebTest/NancyTests.cs | 60 ++++++++++++++----- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs index fc37e69a..833431af 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs @@ -30,39 +30,71 @@ using System; +using Nancy; using Nancy.Testing; -using NSubstitute; - using NUnit.Framework; +using SharpRaven.Data; + namespace SharpRaven.Nancy.WebTest { [TestFixture] public class NancyTests { - [Test] - public void Post_InvokesRavenClient() + private class TestableRavenClient : RavenClient { - var ravenClient = Substitute.For(); + public TestableRavenClient(IJsonPacketFactory jsonPacketFactory) + : base(jsonPacketFactory) + { + // This constructor must exist so Nancy can inject the NancyContextJsonPacketFactory + // that is registered in SentryRegistrations. @asbjornu + } + + + protected override string Send(JsonPacket packet, Dsn dsn) + { + // Retrieving the GUID from the JsonPacket verifies that + // NancyContextJsonPacketFactory.OnCreate() has been invoked, + // since it will copy the request data from the NancyContext. + // @asbjornu + dynamic data = packet.Request.Data; + return data["GUID"]; + } + } + + [Test] + public void Post_InvokesRavenClientWithNancyContextJsonPacketFactory() + { + var guid = Guid.NewGuid().ToString(); var browser = new Browser(c => { c.Module(); - c.ApplicationStartup((container, pipelines) => container.Register(ravenClient)); + c.ApplicationStartup((container, pipelines) => + { + // Override the IRavenClient implementation so we don't perform + // any HTTP request and can retrieve the GUID so we can later + // assert that it is the same we sent in. @asbjornu + container.Register(); + }); }); - TestDelegate throwing = () => browser.Post("/"); + TestDelegate throwing = () => browser.Post("/", with => + { + // Set the GUID which should be transferred to the SentryRequest + // object in the NancyContextJsonPacketFactory.OnCreate() method. + // @asbjornu + with.FormValue("GUID", guid); + }); var exception = Assert.Throws(throwing); - Assert.That(exception.InnerException, Is.Not.Null); - - var divideByZeroException = exception.InnerException.InnerException; - - Assert.That(divideByZeroException, Is.Not.Null); - Assert.That(divideByZeroException, Is.TypeOf()); + Assert.That(exception.InnerException, Is.TypeOf()); + Assert.That(exception.InnerException.InnerException, Is.TypeOf()); - ravenClient.Received(1).CaptureException(divideByZeroException); + // SentryRequestStartup.Initialize() should set the GUID in Exception.Data. @asbjornu + var loggedGuid = exception.InnerException.InnerException.Data[Configuration.Settings.SentryEventGuid]; + Assert.That(loggedGuid, Is.EqualTo(guid)); } } } \ No newline at end of file From ec61fc56f5ef0bc6e6475c85b882330cb6bc98c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 13:12:23 +0100 Subject: [PATCH 045/171] Added back the simple Post_InvokesRavenClient test, because it is a bit easier to debug than the more complex Post_InvokesRavenClientWithNancyContextJsonPacketFactory and is also registering the IRavenClient in another way, which is good to get covered. --- .../SharpRaven.Nancy.WebTest/NancyTests.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs index 833431af..7b81ddec 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs @@ -33,6 +33,8 @@ using Nancy; using Nancy.Testing; +using NSubstitute; + using NUnit.Framework; using SharpRaven.Data; @@ -64,6 +66,27 @@ protected override string Send(JsonPacket packet, Dsn dsn) } + [Test] + public void Post_InvokesRavenClient() + { + var ravenClient = Substitute.For(); + + var browser = new Browser(c => + { + c.Module(); + c.ApplicationStartup((container, pipelines) => container.Register(ravenClient)); + }); + + TestDelegate throwing = () => browser.Post("/"); + + var exception = Assert.Throws(throwing); + Assert.That(exception.InnerException, Is.TypeOf()); + Assert.That(exception.InnerException.InnerException, Is.TypeOf()); + + ravenClient.Received(1).CaptureException(exception.InnerException.InnerException); + } + + [Test] public void Post_InvokesRavenClientWithNancyContextJsonPacketFactory() { From 1cc2efb1a9cce545c22ff4cf5f8c3df418584412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 13:19:43 +0100 Subject: [PATCH 046/171] Renamed The ConfigurableBootstrapperConfigurator lambda parameter 'c' to 'cfg'. --- src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs index 7b81ddec..7812d2b7 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs @@ -71,10 +71,10 @@ public void Post_InvokesRavenClient() { var ravenClient = Substitute.For(); - var browser = new Browser(c => + var browser = new Browser(cfg => { - c.Module(); - c.ApplicationStartup((container, pipelines) => container.Register(ravenClient)); + cfg.Module(); + cfg.ApplicationStartup((container, pipelines) => container.Register(ravenClient)); }); TestDelegate throwing = () => browser.Post("/"); @@ -91,10 +91,10 @@ public void Post_InvokesRavenClient() public void Post_InvokesRavenClientWithNancyContextJsonPacketFactory() { var guid = Guid.NewGuid().ToString(); - var browser = new Browser(c => + var browser = new Browser(cfg => { - c.Module(); - c.ApplicationStartup((container, pipelines) => + cfg.Module(); + cfg.ApplicationStartup((container, pipelines) => { // Override the IRavenClient implementation so we don't perform // any HTTP request and can retrieve the GUID so we can later From c0dc6f40199d797c192e036126c3451a47321f9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 13:21:51 +0100 Subject: [PATCH 047/171] Added SentryRegistrations test for IRavenClient --- .../SentryRegistrationsTests.cs | 52 +++++++++++++++++++ .../SharpRaven.Nancy.WebTest.csproj | 1 + 2 files changed, 53 insertions(+) create mode 100644 src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs diff --git a/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs b/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs new file mode 100644 index 00000000..aab30964 --- /dev/null +++ b/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs @@ -0,0 +1,52 @@ +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using Nancy.Testing; + +using NUnit.Framework; + +namespace SharpRaven.Nancy.WebTest +{ + [TestFixture] + public class SentryRegistrationsTests + { + [Test] + public void RavenClientIsRegistered() + { + IRavenClient ravenClient = null; + new Browser(cfg => cfg.ApplicationStartup((container, pipelines) => + { + ravenClient = container.Resolve(); + })).Get("/"); + + Assert.That(ravenClient, Is.TypeOf()); + } + } +} \ No newline at end of file diff --git a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj index ab35efc5..a4078d7c 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj +++ b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj @@ -82,6 +82,7 @@ + From 2ba61712a655f3d962c3af0ad2880b2aba5ff0e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 13:23:35 +0100 Subject: [PATCH 048/171] Made a reusable Resolve() method to make testing easier. --- .../SentryRegistrationsTests.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs b/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs index aab30964..1bcd90b7 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs @@ -37,15 +37,25 @@ namespace SharpRaven.Nancy.WebTest [TestFixture] public class SentryRegistrationsTests { - [Test] - public void RavenClientIsRegistered() + private static T Resolve() + where T : class { - IRavenClient ravenClient = null; + T instance = null; + new Browser(cfg => cfg.ApplicationStartup((container, pipelines) => { - ravenClient = container.Resolve(); + instance = container.Resolve(); })).Get("/"); + return instance; + } + + + [Test] + public void RavenClientIsRegistered() + { + var ravenClient = Resolve(); + Assert.That(ravenClient, Is.TypeOf()); } } From cf10eb00bf2e887d63a586370ad48eadb96d3e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 13:25:06 +0100 Subject: [PATCH 049/171] Added SentryRegistrations test for NancyContextJsonPacketFactory. --- .../SentryRegistrationsTests.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs b/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs index 1bcd90b7..1d992ce3 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs @@ -32,6 +32,9 @@ using NUnit.Framework; +using SharpRaven.Data; +using SharpRaven.Nancy.Data; + namespace SharpRaven.Nancy.WebTest { [TestFixture] @@ -51,6 +54,15 @@ private static T Resolve() } + [Test] + public void NancyContextJsonPacketFactoryIsRegistered() + { + var jsonPacketFactory = Resolve(); + + Assert.That(jsonPacketFactory, Is.TypeOf()); + } + + [Test] public void RavenClientIsRegistered() { From ce5deae6bcfe547c25c77418e9942b19e7060617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 13:26:19 +0100 Subject: [PATCH 050/171] Renamed SharpRaven.Nancy.Data.SentryRequest to NancySentryRequest. --- .../Data/NancyContextJsonPacketFactory.cs | 2 +- .../Data/{SentryRequest.cs => NancySentryRequest.cs} | 12 ++++++------ src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) rename src/app/SharpRaven.Nancy/Data/{SentryRequest.cs => NancySentryRequest.cs} (94%) diff --git a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs index dc0fa296..d2c53935 100644 --- a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs +++ b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs @@ -58,7 +58,7 @@ protected override JsonPacket OnCreate(JsonPacket jsonPacket) if (nancyContext == null) return jsonPacket; - var sentryRequest = SentryRequest.GetRequest(nancyContext); + var sentryRequest = NancySentryRequest.GetRequest(nancyContext); if (sentryRequest == null) return jsonPacket; diff --git a/src/app/SharpRaven.Nancy/Data/SentryRequest.cs b/src/app/SharpRaven.Nancy/Data/NancySentryRequest.cs similarity index 94% rename from src/app/SharpRaven.Nancy/Data/SentryRequest.cs rename to src/app/SharpRaven.Nancy/Data/NancySentryRequest.cs index 9c960130..92dce2ec 100644 --- a/src/app/SharpRaven.Nancy/Data/SentryRequest.cs +++ b/src/app/SharpRaven.Nancy/Data/NancySentryRequest.cs @@ -46,16 +46,16 @@ namespace SharpRaven.Nancy.Data /// /// The Request information is stored in the Http interface. Two arguments are required: url and method. /// - internal class SentryRequest : ISentryRequest + internal class NancySentryRequest : ISentryRequest { private readonly NancyContext httpContext; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The HTTP context. - internal SentryRequest(NancyContext httpContext) + internal NancySentryRequest(NancyContext httpContext) { this.httpContext = httpContext; @@ -191,11 +191,11 @@ public SentryUser GetUser() /// Gets the request. /// /// - /// If an HTTP contest is available, an instance of , otherwise null. + /// If an HTTP contest is available, an instance of , otherwise null. /// - public static SentryRequest GetRequest(NancyContext httpContext) + public static NancySentryRequest GetRequest(NancyContext httpContext) { - var request = new SentryRequest(httpContext); + var request = new NancySentryRequest(httpContext); return request.HasHttpContext ? request : null; } } diff --git a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj index d7be15a8..c11386fa 100644 --- a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj +++ b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj @@ -74,7 +74,7 @@ - + From 3e27e6fd7a65c9f963c4fd64fb782e84f48ba232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 13:27:02 +0100 Subject: [PATCH 051/171] R# --- src/app/SharpRaven.Nancy/Data/NancySentryRequest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/SharpRaven.Nancy/Data/NancySentryRequest.cs b/src/app/SharpRaven.Nancy/Data/NancySentryRequest.cs index 92dce2ec..66ed3d57 100644 --- a/src/app/SharpRaven.Nancy/Data/NancySentryRequest.cs +++ b/src/app/SharpRaven.Nancy/Data/NancySentryRequest.cs @@ -29,7 +29,6 @@ #endregion using System.Collections.Generic; -using System.IO; using System.Linq; using System.Text; @@ -76,7 +75,7 @@ internal NancySentryRequest(NancyContext httpContext) qs += item + "=" + this.httpContext.Request.Query[item] + "&"; } - QueryString = qs.TrimEnd(new char[] { '&' }); + QueryString = qs.TrimEnd(new[] { '&' }); // Cookies Cookies = this.httpContext.Request.Cookies; From 45c0d882f7c0fe4fc28e93dd021f01205dd09855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 13:28:23 +0100 Subject: [PATCH 052/171] Renamed SharpRaven.Nancy.Configuration to NancyConfiguration to avoid confusion with SharpRaven.Configuration. --- .../Data/NancyContextJsonPacketFactory.cs | 2 +- .../{Configuration.cs => NancyConfiguration.cs} | 8 ++++---- src/app/SharpRaven.Nancy/SentryRegistrations.cs | 2 +- src/app/SharpRaven.Nancy/SentryRequestStartup.cs | 10 +++++----- src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj | 2 +- src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) rename src/app/SharpRaven.Nancy/{Configuration.cs => NancyConfiguration.cs} (95%) diff --git a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs index d2c53935..c7515599 100644 --- a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs +++ b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs @@ -51,7 +51,7 @@ public class NancyContextJsonPacketFactory : JsonPacketFactory /// protected override JsonPacket OnCreate(JsonPacket jsonPacket) { - var nancyContextDataSlot = Configuration.Settings.NancyContextDataSlot; + var nancyContextDataSlot = NancyConfiguration.Settings.NancyContextDataSlot; var localDataStoreSlot = Thread.GetNamedDataSlot(nancyContextDataSlot); var nancyContext = Thread.GetData(localDataStoreSlot) as NancyContext; diff --git a/src/app/SharpRaven.Nancy/Configuration.cs b/src/app/SharpRaven.Nancy/NancyConfiguration.cs similarity index 95% rename from src/app/SharpRaven.Nancy/Configuration.cs rename to src/app/SharpRaven.Nancy/NancyConfiguration.cs index 35f879e3..7aa3c22c 100644 --- a/src/app/SharpRaven.Nancy/Configuration.cs +++ b/src/app/SharpRaven.Nancy/NancyConfiguration.cs @@ -36,13 +36,13 @@ namespace SharpRaven.Nancy /// /// Nancy-specific configuration for SharpRaven. /// - public class Configuration : SharpRaven.Configuration + public class NancyConfiguration : SharpRaven.Configuration { private const string PipelineNameKey = "pipelineName"; private const string CaptureExceptionOnErrorKey = "captureExceptionOnError"; - private static readonly Configuration settings = - ConfigurationManager.GetSection("sharpRaven") as Configuration; + private static readonly NancyConfiguration settings = + ConfigurationManager.GetSection("sharpRaven") as NancyConfiguration; /// /// Gets the <sharpRaven/> configuration element. @@ -50,7 +50,7 @@ public class Configuration : SharpRaven.Configuration /// /// The the <sharpRaven/> configuration element. /// - public new static Configuration Settings + public new static NancyConfiguration Settings { get { return settings; } } diff --git a/src/app/SharpRaven.Nancy/SentryRegistrations.cs b/src/app/SharpRaven.Nancy/SentryRegistrations.cs index fae73973..092fe768 100644 --- a/src/app/SharpRaven.Nancy/SentryRegistrations.cs +++ b/src/app/SharpRaven.Nancy/SentryRegistrations.cs @@ -85,7 +85,7 @@ public IEnumerable InstanceRegistrations //new InstanceRegistration(typeof(Dsn), new Dsn(Configuration.Settings.Dsn.Value)), // TODO: I don't like to register the concrete instance like this, see the above TODO. @asbjornu new InstanceRegistration(typeof(IRavenClient), - new RavenClient(new Dsn(Configuration.Settings.Dsn.Value), + new RavenClient(new Dsn(NancyConfiguration.Settings.Dsn.Value), new NancyContextJsonPacketFactory())), }; } diff --git a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs index 72ecf599..a48873ba 100644 --- a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs +++ b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs @@ -68,21 +68,21 @@ public SentryRequestStartup(IRavenClient ravenClient) /// The current context public void Initialize(IPipelines pipelines, NancyContext context) { - var name = Configuration.Settings.PipelineName.Value; + var name = NancyConfiguration.Settings.PipelineName.Value; var sharpRaven = new PipelineItem(name, (nancyContext, exception) => { - var nancyContextDataSlot = Configuration.Settings.NancyContextDataSlot; + var nancyContextDataSlot = NancyConfiguration.Settings.NancyContextDataSlot; var localDataStoreSlot = Thread.GetNamedDataSlot(nancyContextDataSlot); Thread.SetData(localDataStoreSlot, nancyContext); - if (Configuration.Settings.CaptureExceptionOnError.Value) + if (NancyConfiguration.Settings.CaptureExceptionOnError.Value) { var guid = this.ravenClient.CaptureException(exception); if (guid != null) { - context.Items.Add(Configuration.Settings.SentryEventGuid, guid); - exception.Data.Add(Configuration.Settings.SentryEventGuid, guid); + context.Items.Add(NancyConfiguration.Settings.SentryEventGuid, guid); + exception.Data.Add(NancyConfiguration.Settings.SentryEventGuid, guid); } } diff --git a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj index c11386fa..61acca75 100644 --- a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj +++ b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj @@ -73,7 +73,7 @@ Code - + diff --git a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs index 7812d2b7..5e280242 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs @@ -116,7 +116,7 @@ public void Post_InvokesRavenClientWithNancyContextJsonPacketFactory() Assert.That(exception.InnerException.InnerException, Is.TypeOf()); // SentryRequestStartup.Initialize() should set the GUID in Exception.Data. @asbjornu - var loggedGuid = exception.InnerException.InnerException.Data[Configuration.Settings.SentryEventGuid]; + var loggedGuid = exception.InnerException.InnerException.Data[NancyConfiguration.Settings.SentryEventGuid]; Assert.That(loggedGuid, Is.EqualTo(guid)); } } From ba318bb9522e9c7c61042fa47522a59acb8b1dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 13:28:41 +0100 Subject: [PATCH 053/171] R# --- src/app/SharpRaven.Nancy/NancyConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/SharpRaven.Nancy/NancyConfiguration.cs b/src/app/SharpRaven.Nancy/NancyConfiguration.cs index 7aa3c22c..06f5aadf 100644 --- a/src/app/SharpRaven.Nancy/NancyConfiguration.cs +++ b/src/app/SharpRaven.Nancy/NancyConfiguration.cs @@ -36,7 +36,7 @@ namespace SharpRaven.Nancy /// /// Nancy-specific configuration for SharpRaven. /// - public class NancyConfiguration : SharpRaven.Configuration + public class NancyConfiguration : Configuration { private const string PipelineNameKey = "pipelineName"; private const string CaptureExceptionOnErrorKey = "captureExceptionOnError"; From 955edff63aef232d445fe96fc97c6b8969639b1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 13:50:26 +0100 Subject: [PATCH 054/171] Renamed SharpRaven.Nancy.WebTests to UnitTests to better describe what it's testing. This also makes it easier to set up a wildcard for all tests in TeamCity. --- src/SharpRaven.sln | 2 +- src/tests/SharpRaven.Nancy.WebTest/DefaultModule.cs | 2 +- src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs | 2 +- src/tests/SharpRaven.Nancy.WebTest/Program.cs | 11 ++++------- .../SentryRegistrationsTests.cs | 2 +- ...ebTest.csproj => SharpRaven.Nancy.UnitTest.csproj} | 4 ++-- 6 files changed, 10 insertions(+), 13 deletions(-) rename src/tests/SharpRaven.Nancy.WebTest/{SharpRaven.Nancy.WebTest.csproj => SharpRaven.Nancy.UnitTest.csproj} (97%) diff --git a/src/SharpRaven.sln b/src/SharpRaven.sln index 31734ad5..9215b67f 100644 --- a/src/SharpRaven.sln +++ b/src/SharpRaven.sln @@ -30,7 +30,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpRaven.Nancy", "app\SharpRaven.Nancy\SharpRaven.Nancy.csproj", "{ABE22746-6EEB-4970-A608-C02BC3B8BDA3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpRaven.Nancy.WebTest", "tests\SharpRaven.Nancy.WebTest\SharpRaven.Nancy.WebTest.csproj", "{7FE52A2B-430C-4C6F-BEA9-0855AF973D0C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpRaven.Nancy.UnitTest", "tests\SharpRaven.Nancy.WebTest\SharpRaven.Nancy.UnitTest.csproj", "{7FE52A2B-430C-4C6F-BEA9-0855AF973D0C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/tests/SharpRaven.Nancy.WebTest/DefaultModule.cs b/src/tests/SharpRaven.Nancy.WebTest/DefaultModule.cs index a00b980e..5871d424 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/DefaultModule.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/DefaultModule.cs @@ -30,7 +30,7 @@ using Nancy; -namespace SharpRaven.Nancy.WebTest +namespace SharpRaven.Nancy.UnitTest { public class DefaultModule : NancyModule { diff --git a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs index 5e280242..c9971b6e 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs @@ -39,7 +39,7 @@ using SharpRaven.Data; -namespace SharpRaven.Nancy.WebTest +namespace SharpRaven.Nancy.UnitTest { [TestFixture] public class NancyTests diff --git a/src/tests/SharpRaven.Nancy.WebTest/Program.cs b/src/tests/SharpRaven.Nancy.WebTest/Program.cs index eb0d7d6c..e0795751 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/Program.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/Program.cs @@ -1,11 +1,8 @@ -using Nancy.Hosting.Self; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System; -namespace SharpRaven.Nancy.WebTest +using Nancy.Hosting.Self; + +namespace SharpRaven.Nancy.UnitTest { class Program { diff --git a/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs b/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs index 1d992ce3..cbbc3dc2 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs @@ -35,7 +35,7 @@ using SharpRaven.Data; using SharpRaven.Nancy.Data; -namespace SharpRaven.Nancy.WebTest +namespace SharpRaven.Nancy.UnitTest { [TestFixture] public class SentryRegistrationsTests diff --git a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj similarity index 97% rename from src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj rename to src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj index a4078d7c..e0a6a4d3 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.WebTest.csproj +++ b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj @@ -7,8 +7,8 @@ {7FE52A2B-430C-4C6F-BEA9-0855AF973D0C} Exe Properties - SharpRaven.Nancy.WebTest - SharpRaven.Nancy.WebTest + SharpRaven.Nancy.UnitTest + SharpRaven.Nancy.UnitTest v4.5.1 512 true From 794a5a4bf94e56c8ac131b521180fa9b98a1ca3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 25 Nov 2014 13:57:53 +0100 Subject: [PATCH 055/171] Changed the TargetFramework of SharpRaven.Nancy.UnitTests from .NET 4.5.1 to .NET 4.5 to hopefully make the NUnit runner on TeamCity happy. --- src/tests/SharpRaven.Nancy.WebTest/App.config | 10 +++++----- .../SharpRaven.Nancy.UnitTest.csproj | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/tests/SharpRaven.Nancy.WebTest/App.config b/src/tests/SharpRaven.Nancy.WebTest/App.config index 97b47219..45606623 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/App.config +++ b/src/tests/SharpRaven.Nancy.WebTest/App.config @@ -1,12 +1,12 @@ - + -
+
- + - + - \ No newline at end of file + diff --git a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj index e0a6a4d3..b975bbd8 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj +++ b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj @@ -9,9 +9,10 @@ Properties SharpRaven.Nancy.UnitTest SharpRaven.Nancy.UnitTest - v4.5.1 + v4.5 512 true + bin\Release\net40\ From 9646ecf89538c258b8387a9d05f8ce515352b1ad Mon Sep 17 00:00:00 2001 From: Patrizio Bertozzi Date: Wed, 26 Nov 2014 10:20:09 +0100 Subject: [PATCH 056/171] BugFix missing refactoring on sharRaven section definition --- src/tests/SharpRaven.Nancy.WebTest/App.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/SharpRaven.Nancy.WebTest/App.config b/src/tests/SharpRaven.Nancy.WebTest/App.config index 45606623..ba3d0891 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/App.config +++ b/src/tests/SharpRaven.Nancy.WebTest/App.config @@ -1,7 +1,7 @@ -
+
From 0f6795e8d98b09e04d127473f967e7ebb9e2b5d1 Mon Sep 17 00:00:00 2001 From: Patrizio Bertozzi Date: Wed, 26 Nov 2014 15:06:27 +0100 Subject: [PATCH 057/171] Added nuspec file for SharpRaven.Nancy Added NancyTest to see that IRaveClient is invoked when the user log a message with CaptureMessage Moved set NancyContext to thread data on every request startup and not only OnError callback Added to Build.cmd a command to build SharpRaven.Nancy NuGet packages, with a TODO --- src/Build.cmd | 5 +- .../SharpRaven.Nancy/SentryRequestStartup.cs | 8 ++-- .../SharpRaven.Nancy/SharpRaven.Nancy.csproj | 3 ++ .../SharpRaven.Nancy/SharpRaven.Nancy.nuspec | 25 ++++++++++ src/tests/SharpRaven.Nancy.WebTest/App.config | 3 +- .../SharpRaven.Nancy.WebTest/LogModule.cs | 46 +++++++++++++++++++ .../SharpRaven.Nancy.WebTest/NancyTests.cs | 30 ++++++++++++ .../SharpRaven.Nancy.UnitTest.csproj | 4 ++ src/tests/SharpRaven.Nancy.WebTest/log.html | 10 ++++ 9 files changed, 128 insertions(+), 6 deletions(-) create mode 100644 src/app/SharpRaven.Nancy/SharpRaven.Nancy.nuspec create mode 100644 src/tests/SharpRaven.Nancy.WebTest/LogModule.cs create mode 100644 src/tests/SharpRaven.Nancy.WebTest/log.html diff --git a/src/Build.cmd b/src/Build.cmd index f0dfb37d..75047048 100644 --- a/src/Build.cmd +++ b/src/Build.cmd @@ -29,6 +29,9 @@ echo ===================== echo === NuGet Pack === echo ===================== echo. -NuGet pack app\SharpRaven\SharpRaven.csproj -Properties ReleaseNotes='Test' +NuGet pack app\SharpRaven\SharpRaven.csproj -Properties ReleaseNotes='Test' + +REM TODO: build NuuGet packages with csrproj at the moment getting error "Unable to find 'SharpRaven.Nancy.dll' ..." +NuGet pack app\SharpRaven.Nancy\SharpRaven.Nancy.nuspec -Properties ReleaseNotes='Test' -Verbosity detailed -Version 1.0.0 echo. ENDLOCAL \ No newline at end of file diff --git a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs index a48873ba..89e2ed2a 100644 --- a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs +++ b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs @@ -68,13 +68,13 @@ public SentryRequestStartup(IRavenClient ravenClient) /// The current context public void Initialize(IPipelines pipelines, NancyContext context) { + var nancyContextDataSlot = NancyConfiguration.Settings.NancyContextDataSlot; + var localDataStoreSlot = Thread.GetNamedDataSlot(nancyContextDataSlot); + Thread.SetData(localDataStoreSlot, context); + var name = NancyConfiguration.Settings.PipelineName.Value; var sharpRaven = new PipelineItem(name, (nancyContext, exception) => { - var nancyContextDataSlot = NancyConfiguration.Settings.NancyContextDataSlot; - var localDataStoreSlot = Thread.GetNamedDataSlot(nancyContextDataSlot); - Thread.SetData(localDataStoreSlot, nancyContext); - if (NancyConfiguration.Settings.CaptureExceptionOnError.Value) { var guid = this.ravenClient.CaptureException(exception); diff --git a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj index 61acca75..83ba7b1c 100644 --- a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj +++ b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj @@ -85,6 +85,9 @@ + + Designer + diff --git a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.nuspec b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.nuspec new file mode 100644 index 00000000..559c7e55 --- /dev/null +++ b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.nuspec @@ -0,0 +1,25 @@ + + + + SharpRaven.Nancy + $version$ + .NET client for Sentry (getsentry.com) running on Nancy + Sentry Team + asbjornu, xpicio + https://github.com/getsentry/raven-csharp/blob/master/LICENSE + https://github.com/getsentry/raven-csharp + https://raw.githubusercontent.com/getsentry/raven-csharp/master/sentry-icon.png + false + Raven is a C# client for Sentry (getsentry.com and github.com/getsentry/sentry) + $releaseNotes$ + Copyright 2014 The Sentry Team and individual contributors + raven sentry logging nancy + + + + + + + + + \ No newline at end of file diff --git a/src/tests/SharpRaven.Nancy.WebTest/App.config b/src/tests/SharpRaven.Nancy.WebTest/App.config index ba3d0891..51fa3167 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/App.config +++ b/src/tests/SharpRaven.Nancy.WebTest/App.config @@ -7,6 +7,7 @@ - + + diff --git a/src/tests/SharpRaven.Nancy.WebTest/LogModule.cs b/src/tests/SharpRaven.Nancy.WebTest/LogModule.cs new file mode 100644 index 00000000..c9a3ddd5 --- /dev/null +++ b/src/tests/SharpRaven.Nancy.WebTest/LogModule.cs @@ -0,0 +1,46 @@ +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using Nancy; + +namespace SharpRaven.Nancy.UnitTest +{ + public class LogModule : NancyModule + { + public LogModule(IRavenClient ravenClient) + { + Get["/log"] = _ => + { + string messageId = ravenClient.CaptureMessage("Hello world !!!"); + return View["log.html", new { MessageId = messageId }]; + }; + } + } +} \ No newline at end of file diff --git a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs index c9971b6e..f2f77438 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs @@ -119,5 +119,35 @@ public void Post_InvokesRavenClientWithNancyContextJsonPacketFactory() var loggedGuid = exception.InnerException.InnerException.Data[NancyConfiguration.Settings.SentryEventGuid]; Assert.That(loggedGuid, Is.EqualTo(guid)); } + + [Test] + public void Get_InvokesRavenClientWithNancyContextJsonPacketFactory() + { + var guid = Guid.NewGuid().ToString(); + var browser = new Browser(cfg => + { + cfg.Module(); + cfg.ApplicationStartup((container, pipelines) => + { + // Override the IRavenClient implementation so we don't perform + // any HTTP request and can retrieve the GUID so we can later + // assert that it is the same we sent in. @asbjornu + container.Register(); + }); + }); + + var response = browser.Get("/log", with => + { + with.FormValue("GUID", guid); + }); + + Assert.AreEqual(response.StatusCode, HttpStatusCode.OK); + + response.Body["#message"] + .ShouldExistOnce() + .And.ShouldContain( + guid, + StringComparison.InvariantCultureIgnoreCase); + } } } \ No newline at end of file diff --git a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj index b975bbd8..1fe70db6 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj +++ b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj @@ -79,6 +79,7 @@ + @@ -90,6 +91,9 @@ + + Always + Always diff --git a/src/tests/SharpRaven.Nancy.WebTest/log.html b/src/tests/SharpRaven.Nancy.WebTest/log.html new file mode 100644 index 00000000..2c680eba --- /dev/null +++ b/src/tests/SharpRaven.Nancy.WebTest/log.html @@ -0,0 +1,10 @@ + + + + Message logged! + + +

Message logged!

+

Message id: @Model.MessageId

+ + \ No newline at end of file From aa405763733dfbd41f80b1cd53c4d9841194e641 Mon Sep 17 00:00:00 2001 From: Patrizio Bertozzi Date: Wed, 26 Nov 2014 16:31:27 +0100 Subject: [PATCH 058/171] BugFix when an error occured the NancyContext on current thread is null Cleanup app.config --- src/app/SharpRaven.Nancy/SentryRequestStartup.cs | 6 ++++++ src/tests/SharpRaven.Nancy.WebTest/App.config | 3 +-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs index 89e2ed2a..151ceced 100644 --- a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs +++ b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs @@ -70,11 +70,17 @@ public void Initialize(IPipelines pipelines, NancyContext context) { var nancyContextDataSlot = NancyConfiguration.Settings.NancyContextDataSlot; var localDataStoreSlot = Thread.GetNamedDataSlot(nancyContextDataSlot); + // on each request add the NancyContext to the Thread data Thread.SetData(localDataStoreSlot, context); var name = NancyConfiguration.Settings.PipelineName.Value; var sharpRaven = new PipelineItem(name, (nancyContext, exception) => { + // the error should be throw on a differente tread. Add the + // the NancyContext to the Thread data + localDataStoreSlot = Thread.GetNamedDataSlot(nancyContextDataSlot); + Thread.SetData(localDataStoreSlot, nancyContext); + if (NancyConfiguration.Settings.CaptureExceptionOnError.Value) { var guid = this.ravenClient.CaptureException(exception); diff --git a/src/tests/SharpRaven.Nancy.WebTest/App.config b/src/tests/SharpRaven.Nancy.WebTest/App.config index 51fa3167..ba3d0891 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/App.config +++ b/src/tests/SharpRaven.Nancy.WebTest/App.config @@ -7,7 +7,6 @@ - - + From d9a95549e09d325efbae914168976db5c6822904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Thu, 27 Nov 2014 13:00:22 +0100 Subject: [PATCH 059/171] Renamed the SharpRaven.Nancy.WebTest folder to SharpRaven.Nancy.UnitTests so it corresponds to the project it contains. --- src/SharpRaven.sln | 2 +- .../App.config | 0 .../DefaultModule.cs | 0 .../NancyTests.cs | 0 .../Program.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../SentryRegistrationsTests.cs | 0 .../SharpRaven.Nancy.UnitTests.csproj} | 0 .../default.html | 0 .../error.html | 0 .../packages.config | 0 11 files changed, 1 insertion(+), 1 deletion(-) rename src/tests/{SharpRaven.Nancy.WebTest => SharpRaven.Nancy.UnitTests}/App.config (100%) rename src/tests/{SharpRaven.Nancy.WebTest => SharpRaven.Nancy.UnitTests}/DefaultModule.cs (100%) rename src/tests/{SharpRaven.Nancy.WebTest => SharpRaven.Nancy.UnitTests}/NancyTests.cs (100%) rename src/tests/{SharpRaven.Nancy.WebTest => SharpRaven.Nancy.UnitTests}/Program.cs (100%) rename src/tests/{SharpRaven.Nancy.WebTest => SharpRaven.Nancy.UnitTests}/Properties/AssemblyInfo.cs (100%) rename src/tests/{SharpRaven.Nancy.WebTest => SharpRaven.Nancy.UnitTests}/SentryRegistrationsTests.cs (100%) rename src/tests/{SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj => SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj} (100%) rename src/tests/{SharpRaven.Nancy.WebTest => SharpRaven.Nancy.UnitTests}/default.html (100%) rename src/tests/{SharpRaven.Nancy.WebTest => SharpRaven.Nancy.UnitTests}/error.html (100%) rename src/tests/{SharpRaven.Nancy.WebTest => SharpRaven.Nancy.UnitTests}/packages.config (100%) diff --git a/src/SharpRaven.sln b/src/SharpRaven.sln index 9215b67f..53b8eb51 100644 --- a/src/SharpRaven.sln +++ b/src/SharpRaven.sln @@ -30,7 +30,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpRaven.Nancy", "app\SharpRaven.Nancy\SharpRaven.Nancy.csproj", "{ABE22746-6EEB-4970-A608-C02BC3B8BDA3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpRaven.Nancy.UnitTest", "tests\SharpRaven.Nancy.WebTest\SharpRaven.Nancy.UnitTest.csproj", "{7FE52A2B-430C-4C6F-BEA9-0855AF973D0C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpRaven.Nancy.UnitTests", "tests\SharpRaven.Nancy.UnitTests\SharpRaven.Nancy.UnitTests.csproj", "{7FE52A2B-430C-4C6F-BEA9-0855AF973D0C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/tests/SharpRaven.Nancy.WebTest/App.config b/src/tests/SharpRaven.Nancy.UnitTests/App.config similarity index 100% rename from src/tests/SharpRaven.Nancy.WebTest/App.config rename to src/tests/SharpRaven.Nancy.UnitTests/App.config diff --git a/src/tests/SharpRaven.Nancy.WebTest/DefaultModule.cs b/src/tests/SharpRaven.Nancy.UnitTests/DefaultModule.cs similarity index 100% rename from src/tests/SharpRaven.Nancy.WebTest/DefaultModule.cs rename to src/tests/SharpRaven.Nancy.UnitTests/DefaultModule.cs diff --git a/src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs similarity index 100% rename from src/tests/SharpRaven.Nancy.WebTest/NancyTests.cs rename to src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs diff --git a/src/tests/SharpRaven.Nancy.WebTest/Program.cs b/src/tests/SharpRaven.Nancy.UnitTests/Program.cs similarity index 100% rename from src/tests/SharpRaven.Nancy.WebTest/Program.cs rename to src/tests/SharpRaven.Nancy.UnitTests/Program.cs diff --git a/src/tests/SharpRaven.Nancy.WebTest/Properties/AssemblyInfo.cs b/src/tests/SharpRaven.Nancy.UnitTests/Properties/AssemblyInfo.cs similarity index 100% rename from src/tests/SharpRaven.Nancy.WebTest/Properties/AssemblyInfo.cs rename to src/tests/SharpRaven.Nancy.UnitTests/Properties/AssemblyInfo.cs diff --git a/src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs b/src/tests/SharpRaven.Nancy.UnitTests/SentryRegistrationsTests.cs similarity index 100% rename from src/tests/SharpRaven.Nancy.WebTest/SentryRegistrationsTests.cs rename to src/tests/SharpRaven.Nancy.UnitTests/SentryRegistrationsTests.cs diff --git a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj b/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj similarity index 100% rename from src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj rename to src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj diff --git a/src/tests/SharpRaven.Nancy.WebTest/default.html b/src/tests/SharpRaven.Nancy.UnitTests/default.html similarity index 100% rename from src/tests/SharpRaven.Nancy.WebTest/default.html rename to src/tests/SharpRaven.Nancy.UnitTests/default.html diff --git a/src/tests/SharpRaven.Nancy.WebTest/error.html b/src/tests/SharpRaven.Nancy.UnitTests/error.html similarity index 100% rename from src/tests/SharpRaven.Nancy.WebTest/error.html rename to src/tests/SharpRaven.Nancy.UnitTests/error.html diff --git a/src/tests/SharpRaven.Nancy.WebTest/packages.config b/src/tests/SharpRaven.Nancy.UnitTests/packages.config similarity index 100% rename from src/tests/SharpRaven.Nancy.WebTest/packages.config rename to src/tests/SharpRaven.Nancy.UnitTests/packages.config From f31792eda75f1441ca0c621f944b54aca1449bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Thu, 27 Nov 2014 13:01:24 +0100 Subject: [PATCH 060/171] Adjusted the namespace of the Nancy UnitTests --- src/tests/SharpRaven.Nancy.UnitTests/DefaultModule.cs | 2 +- src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs | 2 +- src/tests/SharpRaven.Nancy.UnitTests/Program.cs | 2 +- .../SharpRaven.Nancy.UnitTests/SentryRegistrationsTests.cs | 2 +- .../SharpRaven.Nancy.UnitTests.csproj | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tests/SharpRaven.Nancy.UnitTests/DefaultModule.cs b/src/tests/SharpRaven.Nancy.UnitTests/DefaultModule.cs index 5871d424..6f80ee0a 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/DefaultModule.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/DefaultModule.cs @@ -30,7 +30,7 @@ using Nancy; -namespace SharpRaven.Nancy.UnitTest +namespace SharpRaven.Nancy.UnitTests { public class DefaultModule : NancyModule { diff --git a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs index c9971b6e..f5072776 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs @@ -39,7 +39,7 @@ using SharpRaven.Data; -namespace SharpRaven.Nancy.UnitTest +namespace SharpRaven.Nancy.UnitTests { [TestFixture] public class NancyTests diff --git a/src/tests/SharpRaven.Nancy.UnitTests/Program.cs b/src/tests/SharpRaven.Nancy.UnitTests/Program.cs index e0795751..02ec8ea7 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/Program.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/Program.cs @@ -2,7 +2,7 @@ using Nancy.Hosting.Self; -namespace SharpRaven.Nancy.UnitTest +namespace SharpRaven.Nancy.UnitTests { class Program { diff --git a/src/tests/SharpRaven.Nancy.UnitTests/SentryRegistrationsTests.cs b/src/tests/SharpRaven.Nancy.UnitTests/SentryRegistrationsTests.cs index cbbc3dc2..8fee3b12 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/SentryRegistrationsTests.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/SentryRegistrationsTests.cs @@ -35,7 +35,7 @@ using SharpRaven.Data; using SharpRaven.Nancy.Data; -namespace SharpRaven.Nancy.UnitTest +namespace SharpRaven.Nancy.UnitTests { [TestFixture] public class SentryRegistrationsTests diff --git a/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj b/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj index b975bbd8..fcec11e3 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj +++ b/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj @@ -7,8 +7,8 @@ {7FE52A2B-430C-4C6F-BEA9-0855AF973D0C} Exe Properties - SharpRaven.Nancy.UnitTest - SharpRaven.Nancy.UnitTest + SharpRaven.Nancy.UnitTests + SharpRaven.Nancy.UnitTests v4.5 512 true From cc21057bd13e7229c4917b5b2a9046ce3d59c9ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Thu, 27 Nov 2014 13:04:33 +0100 Subject: [PATCH 061/171] Moved the merged files from the WebTest to the UnitTests folder --- .../LogModule.cs | 0 .../log.html | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/tests/{SharpRaven.Nancy.WebTest => SharpRaven.Nancy.UnitTests}/LogModule.cs (100%) rename src/tests/{SharpRaven.Nancy.WebTest => SharpRaven.Nancy.UnitTests}/log.html (100%) diff --git a/src/tests/SharpRaven.Nancy.WebTest/LogModule.cs b/src/tests/SharpRaven.Nancy.UnitTests/LogModule.cs similarity index 100% rename from src/tests/SharpRaven.Nancy.WebTest/LogModule.cs rename to src/tests/SharpRaven.Nancy.UnitTests/LogModule.cs diff --git a/src/tests/SharpRaven.Nancy.WebTest/log.html b/src/tests/SharpRaven.Nancy.UnitTests/log.html similarity index 100% rename from src/tests/SharpRaven.Nancy.WebTest/log.html rename to src/tests/SharpRaven.Nancy.UnitTests/log.html From 1f3f8b2e73080f8aee476cba4116b023c3e00d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Thu, 27 Nov 2014 13:05:27 +0100 Subject: [PATCH 062/171] Adjusted the namespace of the merged `LogModule`. --- src/tests/SharpRaven.Nancy.UnitTests/LogModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/SharpRaven.Nancy.UnitTests/LogModule.cs b/src/tests/SharpRaven.Nancy.UnitTests/LogModule.cs index c9a3ddd5..6d8f3406 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/LogModule.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/LogModule.cs @@ -30,7 +30,7 @@ using Nancy; -namespace SharpRaven.Nancy.UnitTest +namespace SharpRaven.Nancy.UnitTests { public class LogModule : NancyModule { From 32daefed7a09b316d15f581f0b6cf9e0c07c4c52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Thu, 27 Nov 2014 13:34:43 +0100 Subject: [PATCH 063/171] R# --- .../SharpRaven.Nancy.UnitTests/App.config | 12 ++-- .../SharpRaven.Nancy.UnitTests/NancyTests.cs | 61 ++++++++++--------- .../SharpRaven.Nancy.UnitTests/Program.cs | 38 ++++++++++-- .../Properties/AssemblyInfo.cs | 39 +++++++++++- 4 files changed, 107 insertions(+), 43 deletions(-) diff --git a/src/tests/SharpRaven.Nancy.UnitTests/App.config b/src/tests/SharpRaven.Nancy.UnitTests/App.config index ba3d0891..5270acbf 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/App.config +++ b/src/tests/SharpRaven.Nancy.UnitTests/App.config @@ -1,12 +1,12 @@ - + -
+
- - + + - + - + \ No newline at end of file diff --git a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs index ee980e95..bcb233be 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs @@ -66,6 +66,37 @@ protected override string Send(JsonPacket packet, Dsn dsn) } + [Test] + public void Get_InvokesRavenClientWithNancyContextJsonPacketFactory() + { + var guid = Guid.NewGuid().ToString(); + var browser = new Browser(cfg => + { + cfg.Module(); + cfg.ApplicationStartup((container, pipelines) => + { + // Override the IRavenClient implementation so we don't perform + // any HTTP request and can retrieve the GUID so we can later + // assert that it is the same we sent in. @asbjornu + container.Register(); + }); + }); + + var response = browser.Get("/log", with => + { + with.FormValue("GUID", guid); + }); + + Assert.AreEqual(response.StatusCode, HttpStatusCode.OK); + + response.Body["#message"] + .ShouldExistOnce() + .And.ShouldContain( + guid, + StringComparison.InvariantCultureIgnoreCase); + } + + [Test] public void Post_InvokesRavenClient() { @@ -119,35 +150,5 @@ public void Post_InvokesRavenClientWithNancyContextJsonPacketFactory() var loggedGuid = exception.InnerException.InnerException.Data[NancyConfiguration.Settings.SentryEventGuid]; Assert.That(loggedGuid, Is.EqualTo(guid)); } - - [Test] - public void Get_InvokesRavenClientWithNancyContextJsonPacketFactory() - { - var guid = Guid.NewGuid().ToString(); - var browser = new Browser(cfg => - { - cfg.Module(); - cfg.ApplicationStartup((container, pipelines) => - { - // Override the IRavenClient implementation so we don't perform - // any HTTP request and can retrieve the GUID so we can later - // assert that it is the same we sent in. @asbjornu - container.Register(); - }); - }); - - var response = browser.Get("/log", with => - { - with.FormValue("GUID", guid); - }); - - Assert.AreEqual(response.StatusCode, HttpStatusCode.OK); - - response.Body["#message"] - .ShouldExistOnce() - .And.ShouldContain( - guid, - StringComparison.InvariantCultureIgnoreCase); - } } } \ No newline at end of file diff --git a/src/tests/SharpRaven.Nancy.UnitTests/Program.cs b/src/tests/SharpRaven.Nancy.UnitTests/Program.cs index 02ec8ea7..ad4f7171 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/Program.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/Program.cs @@ -1,12 +1,42 @@ -using System; +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; using Nancy.Hosting.Self; namespace SharpRaven.Nancy.UnitTests { - class Program + internal class Program { - static void Main(string[] args) + private static void Main(string[] args) { using (var host = new NancyHost(new Uri("http://localhost:3579"))) { @@ -17,4 +47,4 @@ static void Main(string[] args) } } } -} +} \ No newline at end of file diff --git a/src/tests/SharpRaven.Nancy.UnitTests/Properties/AssemblyInfo.cs b/src/tests/SharpRaven.Nancy.UnitTests/Properties/AssemblyInfo.cs index 34f0ac80..4e01b959 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/Properties/AssemblyInfo.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/Properties/AssemblyInfo.cs @@ -1,10 +1,40 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. + [assembly: AssemblyTitle("SharpRaven.Nancy.WebTest")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] @@ -17,9 +47,11 @@ // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. + [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM + [assembly: Guid("489f93bd-e14c-4b44-8422-955c455d6150")] // Version information for an assembly consists of the following four values: @@ -32,5 +64,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] + [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file From 1fcd63bec937b7948e6c591b7fe7b0c0610b7739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Mon, 1 Dec 2014 08:43:16 +0100 Subject: [PATCH 064/171] Removed unused references --- src/tests/SharpRaven.WebTest/SharpRaven.WebTest.csproj | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/tests/SharpRaven.WebTest/SharpRaven.WebTest.csproj b/src/tests/SharpRaven.WebTest/SharpRaven.WebTest.csproj index 0cfd8dc9..fd6a5239 100644 --- a/src/tests/SharpRaven.WebTest/SharpRaven.WebTest.csproj +++ b/src/tests/SharpRaven.WebTest/SharpRaven.WebTest.csproj @@ -44,13 +44,7 @@ - - - - - - From 9fe3dec83ec9405d398f70b4c70c61c61ba75a25 Mon Sep 17 00:00:00 2001 From: Patrizio Bertozzi Date: Wed, 3 Dec 2014 18:13:44 +0100 Subject: [PATCH 065/171] BugFix NancyContext is lost with async --- .../Data/NancyContextJsonPacketFactory.cs | 4 ++-- src/app/SharpRaven.Nancy/SentryRequestStartup.cs | 11 +++-------- src/tests/SharpRaven.Nancy.WebTest/LogModule.cs | 16 ++++++++++++++++ .../SharpRaven.Nancy.UnitTest.csproj | 1 + 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs index c7515599..21312f51 100644 --- a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs +++ b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs @@ -33,6 +33,7 @@ using Nancy; using SharpRaven.Data; +using System.Runtime.Remoting.Messaging; namespace SharpRaven.Nancy.Data { @@ -52,8 +53,7 @@ public class NancyContextJsonPacketFactory : JsonPacketFactory protected override JsonPacket OnCreate(JsonPacket jsonPacket) { var nancyContextDataSlot = NancyConfiguration.Settings.NancyContextDataSlot; - var localDataStoreSlot = Thread.GetNamedDataSlot(nancyContextDataSlot); - var nancyContext = Thread.GetData(localDataStoreSlot) as NancyContext; + var nancyContext = CallContext.LogicalGetData(nancyContextDataSlot) as NancyContext; if (nancyContext == null) return jsonPacket; diff --git a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs index 151ceced..b7379403 100644 --- a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs +++ b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs @@ -30,6 +30,7 @@ using System; using System.Threading; +using System.Runtime.Remoting.Messaging; using Nancy; using Nancy.Bootstrapper; @@ -68,19 +69,13 @@ public SentryRequestStartup(IRavenClient ravenClient) /// The current context public void Initialize(IPipelines pipelines, NancyContext context) { + // on each request store the NancyContext to the LogicalCallContext var nancyContextDataSlot = NancyConfiguration.Settings.NancyContextDataSlot; - var localDataStoreSlot = Thread.GetNamedDataSlot(nancyContextDataSlot); - // on each request add the NancyContext to the Thread data - Thread.SetData(localDataStoreSlot, context); + CallContext.LogicalSetData(nancyContextDataSlot, context); var name = NancyConfiguration.Settings.PipelineName.Value; var sharpRaven = new PipelineItem(name, (nancyContext, exception) => { - // the error should be throw on a differente tread. Add the - // the NancyContext to the Thread data - localDataStoreSlot = Thread.GetNamedDataSlot(nancyContextDataSlot); - Thread.SetData(localDataStoreSlot, nancyContext); - if (NancyConfiguration.Settings.CaptureExceptionOnError.Value) { var guid = this.ravenClient.CaptureException(exception); diff --git a/src/tests/SharpRaven.Nancy.WebTest/LogModule.cs b/src/tests/SharpRaven.Nancy.WebTest/LogModule.cs index c9a3ddd5..22c2694e 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/LogModule.cs +++ b/src/tests/SharpRaven.Nancy.WebTest/LogModule.cs @@ -30,6 +30,8 @@ using Nancy; +using System.Net.Http; + namespace SharpRaven.Nancy.UnitTest { public class LogModule : NancyModule @@ -41,6 +43,20 @@ public LogModule(IRavenClient ravenClient) string messageId = ravenClient.CaptureMessage("Hello world !!!"); return View["log.html", new { MessageId = messageId }]; }; + + Get["/log-async", runAsync: true] = async (_, token) => + { + HttpClient httpClient = new HttpClient(); + var response = await httpClient.GetAsync("http://www.google.com"); + + response.EnsureSuccessStatusCode(); + + var result = await response.Content.ReadAsStringAsync(); + + string messageId = ravenClient.CaptureMessage("Hello world !!!"); + + return View["log.html", new { MessageId = messageId }]; + }; } } } \ No newline at end of file diff --git a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj index 1fe70db6..fe197189 100644 --- a/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj +++ b/src/tests/SharpRaven.Nancy.WebTest/SharpRaven.Nancy.UnitTest.csproj @@ -77,6 +77,7 @@ + From 33bd5ba49373c5f5667dd4ddd78ddcfb0786c92c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 10 Dec 2014 09:03:51 +0100 Subject: [PATCH 066/171] R# cleanup --- .../Data/NancyContextJsonPacketFactory.cs | 3 +- .../Data/NancySentryRequest.cs | 41 +++++++++---------- .../SharpRaven.Nancy/NancyConfiguration.cs | 38 ++++++++++------- .../SharpRaven.Nancy/SentryRegistrations.cs | 40 +++++++++--------- .../SharpRaven.Nancy/SentryRequestStartup.cs | 1 - src/app/SharpRaven/Configuration.cs | 4 ++ src/app/SharpRaven/Data/ISentryRequest.cs | 2 +- .../Logging/Filters/PhoneNumberFilter.cs | 5 ++- src/app/SharpRaven/RavenClient.cs | 2 +- .../SharpRaven.Nancy.UnitTests/LogModule.cs | 4 +- 10 files changed, 75 insertions(+), 65 deletions(-) diff --git a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs index 21312f51..0d556d6a 100644 --- a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs +++ b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs @@ -28,12 +28,11 @@ #endregion -using System.Threading; +using System.Runtime.Remoting.Messaging; using Nancy; using SharpRaven.Data; -using System.Runtime.Remoting.Messaging; namespace SharpRaven.Nancy.Data { diff --git a/src/app/SharpRaven.Nancy/Data/NancySentryRequest.cs b/src/app/SharpRaven.Nancy/Data/NancySentryRequest.cs index 66ed3d57..69a949b8 100644 --- a/src/app/SharpRaven.Nancy/Data/NancySentryRequest.cs +++ b/src/app/SharpRaven.Nancy/Data/NancySentryRequest.cs @@ -38,8 +38,6 @@ using SharpRaven.Data; -using NancyIO = Nancy.IO; - namespace SharpRaven.Nancy.Data { /// @@ -94,13 +92,6 @@ internal NancySentryRequest(NancyContext httpContext) } - [JsonIgnore] - private bool HasHttpContext - { - get { return this.httpContext != null; } - } - - /// /// Gets or sets the cookies. /// @@ -165,6 +156,25 @@ private bool HasHttpContext [JsonProperty(PropertyName = "url", NullValueHandling = NullValueHandling.Ignore)] public string Url { get; set; } + [JsonIgnore] + private bool HasHttpContext + { + get { return this.httpContext != null; } + } + + + /// + /// Gets the request. + /// + /// + /// If an HTTP contest is available, an instance of , otherwise null. + /// + public static NancySentryRequest GetRequest(NancyContext httpContext) + { + var request = new NancySentryRequest(httpContext); + return request.HasHttpContext ? request : null; + } + /// /// Gets the user. @@ -184,18 +194,5 @@ public SentryUser GetUser() IpAddress = this.httpContext.Request.UserHostAddress }; } - - - /// - /// Gets the request. - /// - /// - /// If an HTTP contest is available, an instance of , otherwise null. - /// - public static NancySentryRequest GetRequest(NancyContext httpContext) - { - var request = new NancySentryRequest(httpContext); - return request.HasHttpContext ? request : null; - } } } \ No newline at end of file diff --git a/src/app/SharpRaven.Nancy/NancyConfiguration.cs b/src/app/SharpRaven.Nancy/NancyConfiguration.cs index 06f5aadf..95a8ea55 100644 --- a/src/app/SharpRaven.Nancy/NancyConfiguration.cs +++ b/src/app/SharpRaven.Nancy/NancyConfiguration.cs @@ -38,8 +38,8 @@ namespace SharpRaven.Nancy /// public class NancyConfiguration : Configuration { - private const string PipelineNameKey = "pipelineName"; private const string CaptureExceptionOnErrorKey = "captureExceptionOnError"; + private const string PipelineNameKey = "pipelineName"; private static readonly NancyConfiguration settings = ConfigurationManager.GetSection("sharpRaven") as NancyConfiguration; @@ -56,28 +56,29 @@ public class NancyConfiguration : Configuration } /// - /// Gets the nancy context data slot. + /// Gets the <captureExceptionOnError /> configuration element. /// /// - /// The nancy context data slot. + /// The <captureExceptionOnError /> configuration element. /// - public string NancyContextDataSlot + [ConfigurationProperty(CaptureExceptionOnErrorKey, IsKey = true)] + public CaptureExceptionOnErrorElement CaptureExceptionOnError { - get { return "SharpRaven.Nancy.NancyContext"; } + get { return (CaptureExceptionOnErrorElement) base[CaptureExceptionOnErrorKey]; } } - /// - /// Gets the key for the GUID returned from Sentry after a successfully logged exception. + /// Gets the nancy context data slot. /// /// - /// The key for the GUID returned from Sentry after a successfully logged exception. + /// The nancy context data slot. /// - public string SentryEventGuid + public string NancyContextDataSlot { - get { return "SharpRaven.Nancy.SentryEventGuid"; } + get { return "SharpRaven.Nancy.NancyContext"; } } + /// /// Gets the <pipelineName /> configuration element. /// @@ -91,17 +92,18 @@ public PipelineNameElement PipelineName } /// - /// Gets the <captureExceptionOnError /> configuration element. + /// Gets the key for the GUID returned from Sentry after a successfully logged exception. /// /// - /// The <captureExceptionOnError /> configuration element. + /// The key for the GUID returned from Sentry after a successfully logged exception. /// - [ConfigurationProperty(CaptureExceptionOnErrorKey, IsKey = true)] - public CaptureExceptionOnErrorElement CaptureExceptionOnError + public string SentryEventGuid { - get { return (CaptureExceptionOnErrorElement) base[CaptureExceptionOnErrorKey]; } + get { return "SharpRaven.Nancy.SentryEventGuid"; } } + #region Nested type: CaptureExceptionOnErrorElement + /// /// The <captureExceptionOnError /> configuration element. /// @@ -121,6 +123,10 @@ public bool Value } } + #endregion + + #region Nested type: PipelineNameElement + /// /// The <pipelineName /> configuration element. /// @@ -139,5 +145,7 @@ public String Value set { this["value"] = value; } } } + + #endregion } } \ No newline at end of file diff --git a/src/app/SharpRaven.Nancy/SentryRegistrations.cs b/src/app/SharpRaven.Nancy/SentryRegistrations.cs index 092fe768..b2bd4fc2 100644 --- a/src/app/SharpRaven.Nancy/SentryRegistrations.cs +++ b/src/app/SharpRaven.Nancy/SentryRegistrations.cs @@ -45,26 +45,6 @@ namespace SharpRaven.Nancy /// public class SentryRegistrations : IRegistrations { - /// - /// Gets the type registrations to register for this startup task - /// - public IEnumerable TypeRegistrations - { - get - { - return new[] - { - new TypeRegistration(typeof(IJsonPacketFactory), - typeof(NancyContextJsonPacketFactory), - Lifetime.Singleton), - // TODO: I'd like to register the RavenClient like this so it's more composable and IoC friendly, but I'm seemingly unable to override their registration, which makes testing impossible. @asbjornu - /*new TypeRegistration(typeof(IRavenClient), - typeof(RavenClient), - Lifetime.PerRequest),*/ - }; - } - } - /// /// Gets the collection registrations to register for this startup task /// @@ -90,5 +70,25 @@ public IEnumerable InstanceRegistrations }; } } + + /// + /// Gets the type registrations to register for this startup task + /// + public IEnumerable TypeRegistrations + { + get + { + return new[] + { + new TypeRegistration(typeof(IJsonPacketFactory), + typeof(NancyContextJsonPacketFactory), + Lifetime.Singleton), + // TODO: I'd like to register the RavenClient like this so it's more composable and IoC friendly, but I'm seemingly unable to override their registration, which makes testing impossible. @asbjornu + /*new TypeRegistration(typeof(IRavenClient), + typeof(RavenClient), + Lifetime.PerRequest),*/ + }; + } + } } } \ No newline at end of file diff --git a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs index b7379403..521adfc9 100644 --- a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs +++ b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs @@ -29,7 +29,6 @@ #endregion using System; -using System.Threading; using System.Runtime.Remoting.Messaging; using Nancy; diff --git a/src/app/SharpRaven/Configuration.cs b/src/app/SharpRaven/Configuration.cs index 74d00ba6..93e4151f 100644 --- a/src/app/SharpRaven/Configuration.cs +++ b/src/app/SharpRaven/Configuration.cs @@ -66,6 +66,8 @@ public DsnElement Dsn get { return (DsnElement) base[DsnKey]; } } + #region Nested type: DsnElement + /// /// The <dsn/> configuration element. /// @@ -84,5 +86,7 @@ public String Value set { this["value"] = value; } } } + + #endregion } } \ No newline at end of file diff --git a/src/app/SharpRaven/Data/ISentryRequest.cs b/src/app/SharpRaven/Data/ISentryRequest.cs index 06874068..e5e6406c 100644 --- a/src/app/SharpRaven/Data/ISentryRequest.cs +++ b/src/app/SharpRaven/Data/ISentryRequest.cs @@ -28,7 +28,6 @@ #endregion -using System; using System.Collections.Generic; namespace SharpRaven.Data @@ -95,6 +94,7 @@ public interface ISentryRequest /// string Url { get; set; } + /// /// Gets the user. /// diff --git a/src/app/SharpRaven/Logging/Filters/PhoneNumberFilter.cs b/src/app/SharpRaven/Logging/Filters/PhoneNumberFilter.cs index 07b444cf..be6cbc61 100644 --- a/src/app/SharpRaven/Logging/Filters/PhoneNumberFilter.cs +++ b/src/app/SharpRaven/Logging/Filters/PhoneNumberFilter.cs @@ -43,7 +43,10 @@ public class PhoneNumberFilter : IFilter public string Filter(string input) { Regex phoneRegex = new Regex(@"1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?"); - return phoneRegex.Replace(input, delegate { return "##-PHONE-TRUNC-##"; }); + return phoneRegex.Replace(input, delegate + { + return "##-PHONE-TRUNC-##"; + }); } } } \ No newline at end of file diff --git a/src/app/SharpRaven/RavenClient.cs b/src/app/SharpRaven/RavenClient.cs index 90c6921f..4ee700eb 100644 --- a/src/app/SharpRaven/RavenClient.cs +++ b/src/app/SharpRaven/RavenClient.cs @@ -299,4 +299,4 @@ public string CaptureEvent(Exception e, Dictionary tags) #endregion } -} +} \ No newline at end of file diff --git a/src/tests/SharpRaven.Nancy.UnitTests/LogModule.cs b/src/tests/SharpRaven.Nancy.UnitTests/LogModule.cs index d6494823..b3d5830a 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/LogModule.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/LogModule.cs @@ -28,10 +28,10 @@ #endregion -using Nancy; - using System.Net.Http; +using Nancy; + namespace SharpRaven.Nancy.UnitTests { public class LogModule : NancyModule From fa10b6fdb68e18fc27203a1aaf14a539158c1343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 10 Dec 2014 09:09:26 +0100 Subject: [PATCH 067/171] Repositories.config suddenly discovered the Nancy unit test project. Congratulations! --- src/packages/repositories.config | 1 + 1 file changed, 1 insertion(+) diff --git a/src/packages/repositories.config b/src/packages/repositories.config index cfabae81..9abb9828 100644 --- a/src/packages/repositories.config +++ b/src/packages/repositories.config @@ -2,6 +2,7 @@ + \ No newline at end of file From 9801304ef680ba63e7a536d25bea1612176cdcff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 10 Dec 2014 09:09:57 +0100 Subject: [PATCH 068/171] Make the SharpRaven dependency for the same version as SharpRaven.Nancy with $version$. --- src/app/SharpRaven.Nancy/SharpRaven.Nancy.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.nuspec b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.nuspec index 559c7e55..0cc7554b 100644 --- a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.nuspec +++ b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.nuspec @@ -16,7 +16,7 @@ raven sentry logging nancy - + From 771089384ef587ec9e87f727a5ac338b5243018c Mon Sep 17 00:00:00 2001 From: Benjamin Pannell Date: Thu, 12 Feb 2015 16:30:50 +0200 Subject: [PATCH 069/171] Fixed error handling for tests --- src/app/SharpRaven/IRavenClient.cs | 29 ++++--- src/app/SharpRaven/RavenClient.cs | 85 ++++++++++--------- src/app/SharpRaven/Utilities/GzipUtil.cs | 18 ++++ .../SharpRaven.UnitTests/RavenClientTests.cs | 29 ++++++- 4 files changed, 107 insertions(+), 54 deletions(-) diff --git a/src/app/SharpRaven/IRavenClient.cs b/src/app/SharpRaven/IRavenClient.cs index ba3c99c4..b49d937e 100644 --- a/src/app/SharpRaven/IRavenClient.cs +++ b/src/app/SharpRaven/IRavenClient.cs @@ -92,6 +92,7 @@ string CaptureException(Exception exception, object extra = null); +#if (!net40) /// /// Captures the . /// @@ -104,10 +105,11 @@ string CaptureException(Exception exception, /// The of the successfully captured , or null if it fails. /// Task CaptureExceptionAsync(Exception exception, - string message = null, + SentryMessage message = null, ErrorLevel level = ErrorLevel.Error, IDictionary tags = null, object extra = null); +#endif /// @@ -127,21 +129,22 @@ string CaptureMessage(SentryMessage message, #region Deprecated Methods - - /// - /// Captures the message. - /// - /// The message to capture. - /// The of the captured . Default . - /// The tags to annotate the captured with. - /// The extra metadata to send with the captured . - /// - /// The of the successfully captured , or null if it fails. - /// - Task CaptureMessageAsync(string message, +#if (!net40) + /// + /// Captures the message. + /// + /// The message to capture. + /// The of the captured . Default . + /// The tags to annotate the captured with. + /// The extra metadata to send with the captured . + /// + /// The of the successfully captured , or null if it fails. + /// + Task CaptureMessageAsync(SentryMessage message, ErrorLevel level = ErrorLevel.Info, Dictionary tags = null, object extra = null); +#endif /// /// Captures the event. diff --git a/src/app/SharpRaven/RavenClient.cs b/src/app/SharpRaven/RavenClient.cs index 15b4df9a..2aeaed1d 100644 --- a/src/app/SharpRaven/RavenClient.cs +++ b/src/app/SharpRaven/RavenClient.cs @@ -293,57 +293,64 @@ private string HandleException(Exception exception) protected virtual string Send(JsonPacket packet, Dsn dsn) { packet.Logger = Logger; + try + { - var request = (HttpWebRequest)WebRequest.Create(dsn.SentryUri); - request.Timeout = (int)Timeout.TotalMilliseconds; - request.ReadWriteTimeout = (int)Timeout.TotalMilliseconds; - request.Method = "POST"; - request.Accept = "application/json"; - request.Headers.Add("X-Sentry-Auth", PacketBuilder.CreateAuthenticationHeader(dsn)); - request.UserAgent = PacketBuilder.UserAgent; + var request = (HttpWebRequest)WebRequest.Create(dsn.SentryUri); + request.Timeout = (int)Timeout.TotalMilliseconds; + request.ReadWriteTimeout = (int)Timeout.TotalMilliseconds; + request.Method = "POST"; + request.Accept = "application/json"; + request.Headers.Add("X-Sentry-Auth", PacketBuilder.CreateAuthenticationHeader(dsn)); + request.UserAgent = PacketBuilder.UserAgent; - if (Compression) - { - request.Headers.Add(HttpRequestHeader.ContentEncoding, "gzip"); - request.AutomaticDecompression = DecompressionMethods.Deflate; - request.ContentType = "application/octet-stream"; - } - else - request.ContentType = "application/json; charset=utf-8"; + if (Compression) + { + request.Headers.Add(HttpRequestHeader.ContentEncoding, "gzip"); + request.AutomaticDecompression = DecompressionMethods.Deflate; + request.ContentType = "application/octet-stream"; + } + else + request.ContentType = "application/json; charset=utf-8"; - /*string data = packet.ToString(Formatting.Indented); - Console.WriteLine(data);*/ + /*string data = packet.ToString(Formatting.Indented); + Console.WriteLine(data);*/ - string data = packet.ToString(Formatting.None); + string data = packet.ToString(Formatting.None); - if (LogScrubber != null) - data = LogScrubber.Scrub(data); + if (LogScrubber != null) + data = LogScrubber.Scrub(data); - // Write the messagebody. - using (Stream s = request.GetRequestStream()) - { - if (Compression) - GzipUtil.Write(data, s); - else + // Write the messagebody. + using (Stream s = request.GetRequestStream()) { - using (StreamWriter sw = new StreamWriter(s)) - sw.Write(data); + if (Compression) + GzipUtil.Write(data, s); + else + { + using (StreamWriter sw = new StreamWriter(s)) + sw.Write(data); + } } - } - using (HttpWebResponse wr = (HttpWebResponse)request.GetResponse()) - using (Stream responseStream = wr.GetResponseStream()) - { - if (responseStream == null) - return null; - - using (StreamReader sr = new StreamReader(responseStream)) + using (HttpWebResponse wr = (HttpWebResponse)request.GetResponse()) + using (Stream responseStream = wr.GetResponseStream()) { - string content = sr.ReadToEnd(); - var response = JsonConvert.DeserializeObject(content); - return response.id; + if (responseStream == null) + return null; + + using (StreamReader sr = new StreamReader(responseStream)) + { + string content = sr.ReadToEnd(); + var response = JsonConvert.DeserializeObject(content); + return response.id; + } } } + catch (Exception ex) + { + return HandleException(ex); + } } diff --git a/src/app/SharpRaven/Utilities/GzipUtil.cs b/src/app/SharpRaven/Utilities/GzipUtil.cs index 6301be04..2583e9b0 100644 --- a/src/app/SharpRaven/Utilities/GzipUtil.cs +++ b/src/app/SharpRaven/Utilities/GzipUtil.cs @@ -32,6 +32,10 @@ using System.IO.Compression; using System.Text; +#if (!net40) +using System.Threading.Tasks; +#endif + namespace SharpRaven.Utilities { /// @@ -52,5 +56,19 @@ public static void Write(string json, Stream stream) using (GZipStream gzip = new GZipStream(stream, CompressionMode.Compress)) gzip.Write(data, 0, data.Length); } + +#if(!net40) + /// + /// Compress a JSON string with base-64 encoded gzip compressed string. + /// + /// The JSON to write. + /// The stream. + public static async Task WriteAsync(string json, Stream stream) + { + byte[] data = Encoding.UTF8.GetBytes(json); + using (GZipStream gzip = new GZipStream(stream, CompressionMode.Compress)) + await gzip.WriteAsync(data, 0, data.Length); + } +#endif } } \ No newline at end of file diff --git a/src/tests/SharpRaven.UnitTests/RavenClientTests.cs b/src/tests/SharpRaven.UnitTests/RavenClientTests.cs index da9f01f3..370aa6ed 100644 --- a/src/tests/SharpRaven.UnitTests/RavenClientTests.cs +++ b/src/tests/SharpRaven.UnitTests/RavenClientTests.cs @@ -30,6 +30,10 @@ using System; +#if (!net40) +using System.Threading.Tasks; +#endif + using NSubstitute; using NUnit.Framework; @@ -49,12 +53,18 @@ public TestableRavenClient(string dsn, IJsonPacketFactory jsonPacketFactory = nu : base(dsn, jsonPacketFactory) { } - - + protected override string Send(JsonPacket packet, Dsn dsn) { return packet.Project; } + +#if(!net40) + protected override Task SendAsync(JsonPacket packet, Dsn dsn) + { + return Task.FromResult(packet.Project); + } +#endif } private class TestableJsonPacketFactory : JsonPacketFactory @@ -90,6 +100,21 @@ public void CaptureMessage_InvokesSend_AndJsonPacketFactoryOnCreate() } +#if (!net40) + [Test] + public async Task CaptureMessageAsync_InvokesSend_AndJsonPacketFactoryOnCreate() + { + const string dsnUri = + "http://7d6466e66155431495bdb4036ba9a04b:4c1cfeab7ebd4c1cb9e18008173a3630@app.getsentry.com/3739"; + var project = Guid.NewGuid().ToString(); + var jsonPacketFactory = new TestableJsonPacketFactory(project); + var client = new TestableRavenClient(dsnUri, jsonPacketFactory); + var result = await client.CaptureMessageAsync("Test"); + + Assert.That(result, Is.EqualTo(project)); + } +#endif + [Test] public void CaptureMessage_ScrubberIsInvoked() { From cc9bc88a9a4fd48ef388dd89dbdda2ce743512e9 Mon Sep 17 00:00:00 2001 From: Benjamin Pannell Date: Thu, 12 Feb 2015 16:31:55 +0200 Subject: [PATCH 070/171] Some more improvements to tests --- .../SharpRaven.UnitTests.csproj | 25 ++++++++++++++++--- .../SharpRaven.UnitTests/packages.config | 1 + 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj b/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj index e4ff161d..5e2bda52 100644 --- a/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj +++ b/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj @@ -20,7 +20,7 @@ full false bin\Debug\net40\ - DEBUG;TRACE + TRACE;DEBUG;net40 prompt 4 false @@ -30,7 +30,7 @@ pdbonly true bin\Release\net40\ - TRACE + TRACE;net40 prompt 4 false @@ -65,9 +65,25 @@ False ..\..\packages\NSubstitute.1.8.0.0\lib\net40\NSubstitute.dll + + ..\..\packages\NUnitTestAdapter.WithFramework.1.2\lib\nunit.core.dll + False + + + ..\..\packages\NUnitTestAdapter.WithFramework.1.2\lib\nunit.core.interfaces.dll + False + False - ..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll + ..\..\packages\NUnitTestAdapter.WithFramework.1.2\lib\nunit.framework.dll + + + ..\..\packages\NUnitTestAdapter.WithFramework.1.2\lib\nunit.util.dll + False + + + ..\..\packages\NUnitTestAdapter.WithFramework.1.2\lib\NUnit.VisualStudio.TestAdapter.dll + False @@ -111,6 +127,9 @@ SharpRaven + + + - false - - - false - - - true - - - false - - - - - - - - - - - $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) - - - - - $(SolutionDir).nuget - - - - $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config - $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config - - - - $(MSBuildProjectDirectory)\packages.config - $(PackagesProjectConfig) - - - - - $(NuGetToolsPath)\NuGet.exe - @(PackageSource) - - "$(NuGetExePath)" - mono --runtime=v4.0.30319 "$(NuGetExePath)" - - $(TargetDir.Trim('\\')) - - -RequireConsent - -NonInteractive - - "$(SolutionDir) " - "$(SolutionDir)" - - - $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) - $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols - - - - RestorePackages; - $(BuildDependsOn); - - - - - $(BuildDependsOn); - BuildPackage; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/SharpRaven.sln b/src/SharpRaven.sln index 3904929e..1f022b8b 100644 --- a/src/SharpRaven.sln +++ b/src/SharpRaven.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 -VisualStudioVersion = 12.0.31101.0 +VisualStudioVersion = 12.0.40418.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpRaven", "app\SharpRaven\SharpRaven.csproj", "{CC80A2E1-AE39-44DE-8DA3-4EEF42F90FB1}" EndProject @@ -8,13 +8,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpRaven.UnitTests", "tes EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpRaven.WebTest", "tests\SharpRaven.WebTest\SharpRaven.WebTest.csproj", "{156621FC-2C48-4CDF-A368-9347BABE9089}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{8A88BBCD-89AC-4593-9B91-A93B9F305ED3}" - ProjectSection(SolutionItems) = preProject - ..\.nuget\NuGet.Config = ..\.nuget\NuGet.Config - ..\.nuget\NuGet.exe = ..\.nuget\NuGet.exe - ..\.nuget\NuGet.targets = ..\.nuget\NuGet.targets - EndProjectSection -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "app", "app", "{88CB5CD6-ACFA-441E-9FBB-E1E06F181B89}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D2B3990A-A048-49F3-A697-A1DAEF82CE7F}" diff --git a/src/app/SharpRaven/SharpRaven.csproj b/src/app/SharpRaven/SharpRaven.csproj index ac20a8db..42e96ea9 100644 --- a/src/app/SharpRaven/SharpRaven.csproj +++ b/src/app/SharpRaven/SharpRaven.csproj @@ -13,7 +13,6 @@ v4.5 512 ..\ - true 4140b34f @@ -111,12 +110,5 @@ - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - \ No newline at end of file diff --git a/src/tests/SharpRaven.UnitTests/Integration/NuGetTests.cs b/src/tests/SharpRaven.UnitTests/Integration/NuGetTests.cs index cd070252..0231657f 100644 --- a/src/tests/SharpRaven.UnitTests/Integration/NuGetTests.cs +++ b/src/tests/SharpRaven.UnitTests/Integration/NuGetTests.cs @@ -45,6 +45,7 @@ namespace SharpRaven.UnitTests.Integration public class NuGetTests { [Test] + [Ignore("Figure out a way to test NuGet Pack without having a local reference to NuGet.")] public void Pack_Works() { string pathToNuGet = MakeAbsolute(@".nuget\NuGet.exe"); diff --git a/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj b/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj index 4b615735..375e9f8e 100644 --- a/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj +++ b/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj @@ -1,4 +1,4 @@ - + @@ -12,7 +12,6 @@ v4.5 512 ..\ - true @@ -112,7 +111,6 @@ - \ No newline at end of file diff --git a/src/app/SharpRaven/SharpRaven.csproj b/src/app/SharpRaven/SharpRaven.csproj index b069673e..a1983e14 100644 --- a/src/app/SharpRaven/SharpRaven.csproj +++ b/src/app/SharpRaven/SharpRaven.csproj @@ -1,10 +1,9 @@  + - Release 4.5 + Release 4.5 AnyCPU - 8.0.30703 - 2.0 {CC80A2E1-AE39-44DE-8DA3-4EEF42F90FB1} Library Properties @@ -13,11 +12,10 @@ v4.5 512 ..\ - true 56027b9c - + true full false @@ -26,10 +24,11 @@ prompt 4 bin\Debug\net40\SharpRaven.xml + MinimumRecommendedRules.ruleset false v4.0 - + pdbonly true bin\Release\net40\ @@ -37,6 +36,7 @@ prompt 4 bin\Release\net40\SharpRaven.xml + MinimumRecommendedRules.ruleset false v4.0 @@ -44,10 +44,10 @@ true bin\Debug\net45\ DEBUG;TRACE - bin\Debug\net45\SharpRaven.xml full AnyCPU prompt + bin\Debug\net45\SharpRaven.xml MinimumRecommendedRules.ruleset false v4.5 @@ -55,11 +55,11 @@ bin\Release\net45\ TRACE - bin\Release\net45\SharpRaven.xml true pdbonly AnyCPU prompt + bin\Release\net45\SharpRaven.xml MinimumRecommendedRules.ruleset false v4.5 @@ -112,9 +112,7 @@ - - Designer - + From c4cc9bbad4d1eafd822ab43c3f898aed165b9bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 29 Sep 2015 10:24:14 +0200 Subject: [PATCH 104/171] packages.config cleanup --- src/app/SharpRaven.Nancy/packages.config | 6 +++--- src/app/SharpRaven/packages.config | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/SharpRaven.Nancy/packages.config b/src/app/SharpRaven.Nancy/packages.config index ea2dca6f..3bc07124 100644 --- a/src/app/SharpRaven.Nancy/packages.config +++ b/src/app/SharpRaven.Nancy/packages.config @@ -1,6 +1,6 @@  - - - + + + \ No newline at end of file diff --git a/src/app/SharpRaven/packages.config b/src/app/SharpRaven/packages.config index 88a936fa..cf052271 100644 --- a/src/app/SharpRaven/packages.config +++ b/src/app/SharpRaven/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file From 337e1fe5481debb25dee00cdff7876cb609f34a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 29 Sep 2015 10:33:01 +0200 Subject: [PATCH 105/171] Yay. 34b819450087b2f88f9de1a1a748c331c11c8292 actually fixed #81. Rejoice! \o/ --- src/Build.cmd | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Build.cmd b/src/Build.cmd index cfc14bd9..d50790d0 100644 --- a/src/Build.cmd +++ b/src/Build.cmd @@ -30,8 +30,6 @@ echo === NuGet Pack === echo ===================== echo. NuGet pack app\SharpRaven\SharpRaven.csproj -Properties ReleaseNotes='Test' - -rem TODO: https://github.com/getsentry/raven-csharp/issues/81 -NuGet pack app\SharpRaven.Nancy\SharpRaven.Nancy.csproj -Properties ReleaseNotes='Test' -Verbosity detailed +NuGet pack app\SharpRaven.Nancy\SharpRaven.Nancy.csproj -Properties ReleaseNotes='Test' echo. ENDLOCAL \ No newline at end of file From 4c5866c45617bf38db0e5197428dbfbd26d97e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 29 Sep 2015 10:36:43 +0200 Subject: [PATCH 106/171] Upgraded Nancy from v1.2 to v1.3 --- src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj | 4 ++-- src/app/SharpRaven.Nancy/packages.config | 2 +- src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs | 12 ++++-------- .../SharpRaven.Nancy.UnitTests.csproj | 12 ++++++------ src/tests/SharpRaven.Nancy.UnitTests/packages.config | 6 +++--- 5 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj index 9c9eac43..b584953b 100644 --- a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj +++ b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj @@ -65,9 +65,9 @@ v4.5 - + False - ..\..\packages\Nancy.1.2.0\lib\net40\Nancy.dll + ..\..\packages\Nancy.1.3.0\lib\net40\Nancy.dll False diff --git a/src/app/SharpRaven.Nancy/packages.config b/src/app/SharpRaven.Nancy/packages.config index 3bc07124..eae9dac4 100644 --- a/src/app/SharpRaven.Nancy/packages.config +++ b/src/app/SharpRaven.Nancy/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs index 696042d2..73248455 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs @@ -85,11 +85,9 @@ public void Post_InvokesRavenClient() TestDelegate throwing = () => browser.Post("/"); - var exception = Assert.Throws(throwing); - Assert.That(exception.InnerException, Is.TypeOf()); - Assert.That(exception.InnerException.InnerException, Is.TypeOf()); + var exception = Assert.Throws(throwing); - ravenClient.Received(1).CaptureException(exception.InnerException.InnerException); + ravenClient.Received(1).CaptureException(exception); } @@ -117,12 +115,10 @@ public void Post_InvokesRavenClientWithNancyContextJsonPacketFactory() with.FormValue("GUID", guid); }); - var exception = Assert.Throws(throwing); - Assert.That(exception.InnerException, Is.TypeOf()); - Assert.That(exception.InnerException.InnerException, Is.TypeOf()); + var exception = Assert.Throws(throwing); // SentryRequestStartup.Initialize() should set the GUID in Exception.Data. @asbjornu - var loggedGuid = exception.InnerException.InnerException.Data[NancyConfiguration.Settings.SentryEventGuid]; + var loggedGuid = exception.Data[NancyConfiguration.Settings.SentryEventGuid]; Assert.That(loggedGuid, Is.EqualTo(guid)); } diff --git a/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj b/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj index 2f0d375a..f90c6d5b 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj +++ b/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj @@ -61,17 +61,17 @@ ..\..\packages\CsQuery.1.3.4\lib\net40\CsQuery.dll - + False - ..\..\packages\Nancy.1.2.0\lib\net40\Nancy.dll + ..\..\packages\Nancy.1.3.0\lib\net40\Nancy.dll - + False - ..\..\packages\Nancy.Hosting.Self.1.2.0\lib\net40\Nancy.Hosting.Self.dll + ..\..\packages\Nancy.Hosting.Self.1.3.0\lib\net40\Nancy.Hosting.Self.dll - + False - ..\..\packages\Nancy.Testing.1.2.0\lib\net40\Nancy.Testing.dll + ..\..\packages\Nancy.Testing.1.3.0\lib\net40\Nancy.Testing.dll ..\..\packages\NSubstitute.1.8.0.0\lib\net45\NSubstitute.dll diff --git a/src/tests/SharpRaven.Nancy.UnitTests/packages.config b/src/tests/SharpRaven.Nancy.UnitTests/packages.config index b6e7eccd..ccc2b075 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/packages.config +++ b/src/tests/SharpRaven.Nancy.UnitTests/packages.config @@ -2,9 +2,9 @@ - - - + + + \ No newline at end of file From 80848d5a68506dcc429d3223a7d3640a5cb10ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 29 Sep 2015 10:39:59 +0200 Subject: [PATCH 107/171] The NuGet tests aren't useful anymore --- .../Integration/NuGetTests.cs | 88 ------------------- .../SharpRaven.UnitTests.csproj | 1 - 2 files changed, 89 deletions(-) delete mode 100644 src/tests/SharpRaven.UnitTests/Integration/NuGetTests.cs diff --git a/src/tests/SharpRaven.UnitTests/Integration/NuGetTests.cs b/src/tests/SharpRaven.UnitTests/Integration/NuGetTests.cs deleted file mode 100644 index c62771a0..00000000 --- a/src/tests/SharpRaven.UnitTests/Integration/NuGetTests.cs +++ /dev/null @@ -1,88 +0,0 @@ -#region License - -// Copyright (c) 2014 The Sentry Team and individual contributors. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are permitted -// provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list of -// conditions and the following disclaimer in the documentation and/or other materials -// provided with the distribution. -// -// 3. Neither the name of the Sentry nor the names of its contributors may be used to -// endorse or promote products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#endregion - -using System; -using System.Diagnostics; -using System.IO; - -using NUnit.Framework; - -namespace SharpRaven.UnitTests.Integration -{ - /// - /// NuGet tests. These are more integration tests than unit tests, but I can't bother with - /// setting up TeamCity to run more than one test DLL. - /// - [TestFixture] - [Category("NuGet")] - public class NuGetTests - { - [Test] - [Ignore("Figure out a way to test NuGet Pack without having a local reference to NuGet.")] - public void Pack_Works() - { - string pathToNuGet = MakeAbsolute(@".nuget\NuGet.exe"); - string pathToNuSpec = MakeAbsolute(@"src\app\SharpRaven\SharpRaven.nuspec"); - - ProcessStartInfo start = new ProcessStartInfo(pathToNuGet) - { - Arguments = String.Format( - "Pack {0} -Version {1} -Properties Configuration=Release -Properties \"ReleaseNotes=Test\"", - pathToNuSpec, - typeof(IRavenClient).Assembly.GetName().Version), - CreateNoWindow = true, - UseShellExecute = false, - RedirectStandardError = true, - RedirectStandardOutput = true, - WindowStyle = ProcessWindowStyle.Hidden, - }; - - using (var process = new Process()) - { - process.OutputDataReceived += (s, e) => Console.WriteLine(e.Data); - process.ErrorDataReceived += (s, e) => Console.WriteLine(e.Data); - process.StartInfo = start; - Assert.That(process.Start(), Is.True, "The NuGet process couldn't start."); - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); - process.WaitForExit(3000); - Assert.That(process.ExitCode, Is.EqualTo(0), "The NuGet process exited with an unexpected code."); - } - } - - - private static string MakeAbsolute(string relativePath) - { - string absolutePath = Path.Combine(Environment.CurrentDirectory, @"..\..\..\..\..\..\", relativePath); - - return new DirectoryInfo(absolutePath).FullName; - } - } -} \ No newline at end of file diff --git a/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj b/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj index b7cd9995..268a1efc 100644 --- a/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj +++ b/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj @@ -85,7 +85,6 @@ - From e0641b6428d167d188be41d75527402d80936a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 18 Nov 2015 15:29:49 +0100 Subject: [PATCH 108/171] First go at capturing `Exception.Data`. --- src/SharpRaven.sln.DotSettings | 11 +-- src/app/SharpRaven/Data/JsonPacket.cs | 2 +- src/app/SharpRaven/Data/JsonPacketFactory.cs | 68 ++++++++++++++++++- .../Integration/CaptureTests.cs | 42 ++++++++++-- 4 files changed, 111 insertions(+), 12 deletions(-) diff --git a/src/SharpRaven.sln.DotSettings b/src/SharpRaven.sln.DotSettings index dbffea8e..3ba643ef 100644 --- a/src/SharpRaven.sln.DotSettings +++ b/src/SharpRaven.sln.DotSettings @@ -73,7 +73,7 @@ <HasAttribute Name="System.Runtime.InteropServices.ComImport" /> </Or> </And> - <HasAttribute Name="System.Runtime.InteropServices.StructLayoutAttribute" /> + <Kind Is="Struct" /> </Or> </TypePattern.Match> </TypePattern> @@ -110,7 +110,7 @@ <Static /> </Entry.SortBy> </Entry> - <Entry DisplayName="Test Methods" Priority="100"> + <Entry Priority="100" DisplayName="Test Methods"> <Entry.Match> <And> <Kind Is="Method" /> @@ -157,7 +157,7 @@ </Entry> </TypePattern> <TypePattern DisplayName="Default Pattern"> - <Entry DisplayName="Public Delegates" Priority="100"> + <Entry Priority="100" DisplayName="Public Delegates"> <Entry.Match> <And> <Access Is="Public" /> @@ -168,7 +168,7 @@ <Name /> </Entry.SortBy> </Entry> - <Entry DisplayName="Public Enums" Priority="100"> + <Entry Priority="100" DisplayName="Public Enums"> <Entry.Match> <And> <Access Is="Public" /> @@ -226,7 +226,7 @@ <Name Is="Enter Pattern Here" /> </Entry.SortBy> </Entry> - <Entry DisplayName="Interface Implementations" Priority="100"> + <Entry Priority="100" DisplayName="Interface Implementations"> <Entry.Match> <And> <Kind Is="Member" /> @@ -628,6 +628,7 @@ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF S TEMP_FOLDER True True + True True True C:\Programs\NUnit-2.6.3\bin\lib diff --git a/src/app/SharpRaven/Data/JsonPacket.cs b/src/app/SharpRaven/Data/JsonPacket.cs index d2461369..ffc40f1f 100644 --- a/src/app/SharpRaven/Data/JsonPacket.cs +++ b/src/app/SharpRaven/Data/JsonPacket.cs @@ -171,7 +171,7 @@ private JsonPacket() /// An arbitrary mapping of additional metadata to store with the event. /// [JsonProperty(PropertyName = "extra", NullValueHandling = NullValueHandling.Ignore)] - public object Extra { get; set; } + public IDictionary Extra { get; set; } /// /// The record severity. diff --git a/src/app/SharpRaven/Data/JsonPacketFactory.cs b/src/app/SharpRaven/Data/JsonPacketFactory.cs index 8ce4ad33..21b34d48 100644 --- a/src/app/SharpRaven/Data/JsonPacketFactory.cs +++ b/src/app/SharpRaven/Data/JsonPacketFactory.cs @@ -29,6 +29,7 @@ #endregion using System; +using System.Collections; using System.Collections.Generic; namespace SharpRaven.Data @@ -64,7 +65,7 @@ public JsonPacket Create(string project, MessageObject = message, Level = level, Tags = tags, - Extra = extra + Extra = Convert(extra) }; return OnCreate(json); @@ -104,7 +105,7 @@ public JsonPacket Create(string project, MessageObject = message, Level = level, Tags = tags, - Extra = extra + Extra = Convert(extra, exception.Data) }; return OnCreate(json); @@ -123,5 +124,68 @@ protected virtual JsonPacket OnCreate(JsonPacket jsonPacket) { return jsonPacket; } + + + private static IDictionary Convert(object extra, IDictionary data = null) + { + if (data == null && extra == null) + return null; + + var result = new Dictionary(); + + if (extra != null) + { + foreach (var property in extra.GetType().GetProperties()) + { + try + { + var value = property.GetValue(extra); + var key = UniqueKey(result, property.Name); + result.Add(key, value); + } + catch (Exception exception) + { + Console.WriteLine("ERROR: " + exception); + } + } + } + + if (data == null) + return result; + + foreach (var k in data.Keys) + { + try + { + var value = data[k]; + var key = UniqueKey(result, k); + result.Add(key, value); + } + catch (Exception exception) + { + Console.WriteLine("ERROR: " + exception); + } + } + + return result; + } + + + private static string UniqueKey(IDictionary dictionary, object key) + { + var stringKey = key as string ?? key.ToString(); + + if (!dictionary.ContainsKey(stringKey)) + return stringKey; + + for (var i = 0; i < 10000; i++) + { + var newKey = String.Join(stringKey, i); + if (!dictionary.ContainsKey(newKey)) + return stringKey; + } + + throw new ArgumentException(String.Format("Unable to find a unique key for '{0}'.", stringKey), "key"); + } } } \ No newline at end of file diff --git a/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs b/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs index c7740763..b79b3b94 100644 --- a/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs +++ b/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs @@ -32,6 +32,8 @@ using System.Collections.Generic; using System.Linq; +using NSubstitute; + using NUnit.Framework; using SharpRaven.Data; @@ -120,6 +122,34 @@ public void CaptureException_Doesnt_Fail_On_Error_During_Send() } + [Test] + public void CaptureException_WithData_DataIsCaptured() + { + var data = new KeyValuePair("DataKey", Guid.NewGuid().ToString("N")); + + try + { + Helper.FirstLevelException(data); + } + catch (Exception e) + { + // I don't feel OK using LogScrubber for testing this, but we can't test at a (mocked) HTTP level yet. @asbjornu + var logScrubber = Substitute.For(); + + this.ravenClient = new RavenClient(DsnUrl) + { + Logger = "C#", + LogScrubber = logScrubber + }; + + this.ravenClient.CaptureException(e); + + logScrubber.Received(1) + .Scrub(Arg.Is(s => s.Contains(String.Format("\"{0}\":\"{1}\"", data.Key, data.Value)))); + } + } + + [Test] public void CaptureException_WithMessageFormat_ReturnsValidID() { @@ -255,11 +285,11 @@ public void CaptureMessage_WithFormat_ReturnsValidID() private static class Helper { - public static void FirstLevelException() + public static void FirstLevelException(KeyValuePair? data = null) { try { - SecondLevelException(); + SecondLevelException(data); } catch (Exception e) { @@ -284,7 +314,7 @@ private static void PerformDivideByZero() } - private static void SecondLevelException() + private static void SecondLevelException(KeyValuePair? data) { try { @@ -292,7 +322,11 @@ private static void SecondLevelException() } catch (Exception e) { - throw new InvalidOperationException("Second Level Exception", e); + var invalidOperationException = new InvalidOperationException("Second Level Exception", e); + if (data != null) + invalidOperationException.Data.Add(data.Value.Key, data.Value.Value); + + throw invalidOperationException; } } } From ce9f26856de56d37d99a451fec1d38b9081055a5 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Tue, 29 Sep 2015 18:16:30 -0700 Subject: [PATCH 109/171] Update doc config --- docs/sentry-doc-config.json | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/sentry-doc-config.json b/docs/sentry-doc-config.json index aa492acc..d4bf86b8 100644 --- a/docs/sentry-doc-config.json +++ b/docs/sentry-doc-config.json @@ -1,11 +1,10 @@ { - "wizards": { - "c-sharp": { + "platforms": { + "csharp": { "name": "C#", - "client_lib": "raven-csharp", - "is_framework": false, + "type": "language", "doc_link": "", - "snippets": [ + "wizard": [ "index#installation", "index#capturing-exceptions" ] From 49410815c87ee67ac35fc6b80ec8a7fb8c4c7e1f Mon Sep 17 00:00:00 2001 From: Matt Robenolt Date: Fri, 9 Oct 2015 13:58:48 -0700 Subject: [PATCH 110/171] Add support for fingerprinting Fixes GH-72 --- src/app/SharpRaven/Data/JsonPacket.cs | 6 ++++++ src/app/SharpRaven/Data/JsonPacketFactory.cs | 16 ++++++++++------ src/app/SharpRaven/RavenClient.cs | 18 +++++++++++------- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/app/SharpRaven/Data/JsonPacket.cs b/src/app/SharpRaven/Data/JsonPacket.cs index d2461369..45b7ae4e 100644 --- a/src/app/SharpRaven/Data/JsonPacket.cs +++ b/src/app/SharpRaven/Data/JsonPacket.cs @@ -246,6 +246,12 @@ private JsonPacket() [JsonProperty(PropertyName = "server_name", NullValueHandling = NullValueHandling.Ignore)] public string ServerName { get; set; } + /// + /// Gets or sets the fingerprint used for custom grouping + /// + [JsonProperty(PropertyName = "fingerprint", NullValueHandling = NullValueHandling.Ignore)] + public List Fingerprint { get; set; } + /// /// A map or list of tags for this event. /// diff --git a/src/app/SharpRaven/Data/JsonPacketFactory.cs b/src/app/SharpRaven/Data/JsonPacketFactory.cs index 8ce4ad33..e2994f4e 100644 --- a/src/app/SharpRaven/Data/JsonPacketFactory.cs +++ b/src/app/SharpRaven/Data/JsonPacketFactory.cs @@ -2,21 +2,21 @@ // Copyright (c) 2014 The Sentry Team and individual contributors. // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are permitted // provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // 3. Neither the name of the Sentry nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR @@ -56,6 +56,7 @@ public JsonPacket Create(string project, SentryMessage message, ErrorLevel level = ErrorLevel.Info, IDictionary tags = null, + List fingerprint = null, object extra = null) { var json = new JsonPacket(project) @@ -64,6 +65,7 @@ public JsonPacket Create(string project, MessageObject = message, Level = level, Tags = tags, + Fingerprint = fingerprint, Extra = extra }; @@ -96,6 +98,7 @@ public JsonPacket Create(string project, SentryMessage message = null, ErrorLevel level = ErrorLevel.Error, IDictionary tags = null, + List fingerprint = null, object extra = null) { var json = new JsonPacket(project, exception) @@ -104,6 +107,7 @@ public JsonPacket Create(string project, MessageObject = message, Level = level, Tags = tags, + Fingerprint = fingerprint, Extra = extra }; @@ -124,4 +128,4 @@ protected virtual JsonPacket OnCreate(JsonPacket jsonPacket) return jsonPacket; } } -} \ No newline at end of file +} diff --git a/src/app/SharpRaven/RavenClient.cs b/src/app/SharpRaven/RavenClient.cs index 2a7c7047..8a40e7d1 100644 --- a/src/app/SharpRaven/RavenClient.cs +++ b/src/app/SharpRaven/RavenClient.cs @@ -2,21 +2,21 @@ // Copyright (c) 2014 The Sentry Team and individual contributors. // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are permitted // provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // 3. Neither the name of the Sentry nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR @@ -131,7 +131,7 @@ public Dsn CurrentDsn } /// - /// Interface for providing a 'log scrubber' that removes + /// Interface for providing a 'log scrubber' that removes /// sensitive information from exceptions sent to sentry. /// public IScrubber LogScrubber { get; set; } @@ -182,6 +182,7 @@ public string CaptureEvent(Exception e, Dictionary tags) /// The optional messge to capture. Default: . /// The of the captured . Default: . /// The tags to annotate the captured with. + /// The custom fingerprint to annotate the captured with. /// The extra metadata to send with the captured . /// /// The of the successfully captured , or null if it fails. @@ -190,6 +191,7 @@ public string CaptureException(Exception exception, SentryMessage message = null, ErrorLevel level = ErrorLevel.Error, IDictionary tags = null, + List fingerprint = null, object extra = null) { JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, @@ -209,6 +211,7 @@ public string CaptureException(Exception exception, /// The message to capture. /// The of the captured . Default . /// The tags to annotate the captured with. + /// The custom fingerprint to annotate the captured with. /// The extra metadata to send with the captured . /// /// The of the successfully captured , or null if it fails. @@ -216,6 +219,7 @@ public string CaptureException(Exception exception, public string CaptureMessage(SentryMessage message, ErrorLevel level = ErrorLevel.Info, Dictionary tags = null, + List fingerprint = null, object extra = null) { JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, message, level, tags, extra); @@ -355,4 +359,4 @@ private string HandleException(Exception exception) return null; } } -} \ No newline at end of file +} From 014abe80ac131324aa92d31ff2875ede98297125 Mon Sep 17 00:00:00 2001 From: Matt Robenolt Date: Fri, 9 Oct 2015 14:08:26 -0700 Subject: [PATCH 111/171] Add fingerprint to interface --- src/app/SharpRaven/IRavenClient.cs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/app/SharpRaven/IRavenClient.cs b/src/app/SharpRaven/IRavenClient.cs index 29a961d0..0479b534 100644 --- a/src/app/SharpRaven/IRavenClient.cs +++ b/src/app/SharpRaven/IRavenClient.cs @@ -2,21 +2,21 @@ // Copyright (c) 2014 The Sentry Team and individual contributors. // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are permitted // provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // 3. Neither the name of the Sentry nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR @@ -58,14 +58,14 @@ public interface IRavenClient string Logger { get; set; } /// - /// Interface for providing a 'log scrubber' that removes + /// Interface for providing a 'log scrubber' that removes /// sensitive information from exceptions sent to sentry. /// IScrubber LogScrubber { get; set; } /// /// Gets or sets the timeout value in milliseconds for the - /// and methods. + /// and methods. /// /// /// The number of milliseconds to wait before the request times out. The default is 5,000 milliseconds (5 seconds). @@ -81,6 +81,7 @@ public interface IRavenClient /// The optional messge to capture instead of the default . /// The of the captured . Default: . /// The tags to annotate the captured with. + /// The custom fingerprint to annotate the captured with. /// The extra metadata to send with the captured . /// /// The of the successfully captured , or null if it fails. @@ -89,6 +90,7 @@ string CaptureException(Exception exception, SentryMessage message = null, ErrorLevel level = ErrorLevel.Error, IDictionary tags = null, + List fingerprint = null, object extra = null); @@ -118,6 +120,7 @@ Task CaptureExceptionAsync(Exception exception, /// The message to capture. /// The of the captured . Default . /// The tags to annotate the captured with. + /// The custom fingerprint to annotate the captured with. /// The extra metadata to send with the captured . /// /// The of the successfully captured , or null if it fails. @@ -125,6 +128,7 @@ Task CaptureExceptionAsync(Exception exception, string CaptureMessage(SentryMessage message, ErrorLevel level = ErrorLevel.Info, Dictionary tags = null, + List fingerprint = null, object extra = null); #region Deprecated Methods @@ -167,4 +171,4 @@ Task CaptureMessageAsync(SentryMessage message, #endregion } -} \ No newline at end of file +} From 220e4be73b507412c0866e0ba632723017d74b95 Mon Sep 17 00:00:00 2001 From: Matt Robenolt Date: Fri, 9 Oct 2015 15:59:41 -0700 Subject: [PATCH 112/171] Add fingerprint to IJsonPacketFactory --- src/app/SharpRaven/Data/IJsonPacketFactory.cs | 22 +++++++++++-------- src/app/SharpRaven/Data/JsonPacketFactory.cs | 2 ++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/app/SharpRaven/Data/IJsonPacketFactory.cs b/src/app/SharpRaven/Data/IJsonPacketFactory.cs index 994f8a17..a02ea537 100644 --- a/src/app/SharpRaven/Data/IJsonPacketFactory.cs +++ b/src/app/SharpRaven/Data/IJsonPacketFactory.cs @@ -2,21 +2,21 @@ // Copyright (c) 2014 The Sentry Team and individual contributors. // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are permitted // provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // 3. Neither the name of the Sentry nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR @@ -34,11 +34,11 @@ namespace SharpRaven.Data { /// - /// Factory interface for creating + /// Factory interface for creating /// s. To simply adjust the values of a - /// packet before it is sent to Sentry, inherit + /// packet before it is sent to Sentry, inherit /// and override - /// its + /// its /// method. /// public interface IJsonPacketFactory @@ -52,6 +52,7 @@ public interface IJsonPacketFactory /// The message to capture. /// The of the captured . Default . /// The tags to annotate the captured with. + /// The custom fingerprint to annotate the captured with. /// The extra metadata to send with the captured . /// /// A new instance of for the specified . @@ -60,6 +61,7 @@ JsonPacket Create(string project, SentryMessage message, ErrorLevel level = ErrorLevel.Info, IDictionary tags = null, + List fingerprint = null, object extra = null); @@ -75,6 +77,7 @@ JsonPacket Create(string project, /// The optional messge to capture. Default: . /// The of the captured . Default: . /// The tags to annotate the captured with. + /// The custom fingerprint to annotate the captured with. /// The extra metadata to send with the captured . /// /// A new instance of @@ -88,6 +91,7 @@ JsonPacket Create(string project, SentryMessage message = null, ErrorLevel level = ErrorLevel.Error, IDictionary tags = null, + List fingerprint = null, object extra = null); } -} \ No newline at end of file +} diff --git a/src/app/SharpRaven/Data/JsonPacketFactory.cs b/src/app/SharpRaven/Data/JsonPacketFactory.cs index e2994f4e..5846cf1a 100644 --- a/src/app/SharpRaven/Data/JsonPacketFactory.cs +++ b/src/app/SharpRaven/Data/JsonPacketFactory.cs @@ -48,6 +48,7 @@ public class JsonPacketFactory : IJsonPacketFactory /// The message to capture. /// The of the captured . Default . /// The tags to annotate the captured with. + /// The custom fingerprint to annotate the captured with. /// The extra metadata to send with the captured . /// /// A new instance of for the specified . @@ -85,6 +86,7 @@ public JsonPacket Create(string project, /// The optional messge to capture. Default: . /// The of the captured . Default: . /// The tags to annotate the captured with. + /// The custom fingerprint to annotate the captured with. /// The extra metadata to send with the captured . /// /// A new instance of From 5c72f9cdd1939fbee2eaed285dd4d5d9436c6821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 18 Nov 2015 15:46:39 +0100 Subject: [PATCH 113/171] Not sure what R# is up to, but here you go. --- src/SharpRaven.sln.DotSettings | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/SharpRaven.sln.DotSettings b/src/SharpRaven.sln.DotSettings index dbffea8e..3ba643ef 100644 --- a/src/SharpRaven.sln.DotSettings +++ b/src/SharpRaven.sln.DotSettings @@ -73,7 +73,7 @@ <HasAttribute Name="System.Runtime.InteropServices.ComImport" /> </Or> </And> - <HasAttribute Name="System.Runtime.InteropServices.StructLayoutAttribute" /> + <Kind Is="Struct" /> </Or> </TypePattern.Match> </TypePattern> @@ -110,7 +110,7 @@ <Static /> </Entry.SortBy> </Entry> - <Entry DisplayName="Test Methods" Priority="100"> + <Entry Priority="100" DisplayName="Test Methods"> <Entry.Match> <And> <Kind Is="Method" /> @@ -157,7 +157,7 @@ </Entry> </TypePattern> <TypePattern DisplayName="Default Pattern"> - <Entry DisplayName="Public Delegates" Priority="100"> + <Entry Priority="100" DisplayName="Public Delegates"> <Entry.Match> <And> <Access Is="Public" /> @@ -168,7 +168,7 @@ <Name /> </Entry.SortBy> </Entry> - <Entry DisplayName="Public Enums" Priority="100"> + <Entry Priority="100" DisplayName="Public Enums"> <Entry.Match> <And> <Access Is="Public" /> @@ -226,7 +226,7 @@ <Name Is="Enter Pattern Here" /> </Entry.SortBy> </Entry> - <Entry DisplayName="Interface Implementations" Priority="100"> + <Entry Priority="100" DisplayName="Interface Implementations"> <Entry.Match> <And> <Kind Is="Member" /> @@ -628,6 +628,7 @@ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF S TEMP_FOLDER True True + True True True C:\Programs\NUnit-2.6.3\bin\lib From 33e09258b2e39235b9f19fc4be011448ef1e78d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 18 Nov 2015 15:46:51 +0100 Subject: [PATCH 114/171] Added fingerprint to the async methods --- src/app/SharpRaven/IRavenClient.cs | 17 +++++++++++------ src/app/SharpRaven/RavenClient.Net45.cs | 7 ++++++- src/app/SharpRaven/RavenClient.cs | 15 ++++++++------- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/app/SharpRaven/IRavenClient.cs b/src/app/SharpRaven/IRavenClient.cs index 0479b534..9e7eb8ee 100644 --- a/src/app/SharpRaven/IRavenClient.cs +++ b/src/app/SharpRaven/IRavenClient.cs @@ -2,21 +2,21 @@ // Copyright (c) 2014 The Sentry Team and individual contributors. // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are permitted // provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // 3. Neither the name of the Sentry nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR @@ -102,6 +102,7 @@ string CaptureException(Exception exception, /// The optional messge to capture instead of the default . /// The of the captured . Default: . /// The tags to annotate the captured with. + /// The custom fingerprint to annotate the captured with. /// The extra metadata to send with the captured . /// /// The of the successfully captured , or null if it fails. @@ -110,7 +111,9 @@ Task CaptureExceptionAsync(Exception exception, SentryMessage message = null, ErrorLevel level = ErrorLevel.Error, IDictionary tags = null, + List fingerprint = null, object extra = null); + #endif @@ -140,6 +143,7 @@ string CaptureMessage(SentryMessage message, /// The message to capture. /// The of the captured . Default . /// The tags to annotate the captured with. + /// The custom fingerprint to annotate the captured with. /// The extra metadata to send with the captured . /// /// The of the successfully captured , or null if it fails. @@ -147,6 +151,7 @@ string CaptureMessage(SentryMessage message, Task CaptureMessageAsync(SentryMessage message, ErrorLevel level = ErrorLevel.Info, Dictionary tags = null, + List fingerprint = null, object extra = null); #endif @@ -171,4 +176,4 @@ Task CaptureMessageAsync(SentryMessage message, #endregion } -} +} \ No newline at end of file diff --git a/src/app/SharpRaven/RavenClient.Net45.cs b/src/app/SharpRaven/RavenClient.Net45.cs index 80d23fc8..ec6bc8ba 100644 --- a/src/app/SharpRaven/RavenClient.Net45.cs +++ b/src/app/SharpRaven/RavenClient.Net45.cs @@ -55,6 +55,7 @@ public partial class RavenClient /// The optional messge to capture. Default: . /// The of the captured . Default: . /// The tags to annotate the captured with. + /// The custom fingerprint to annotate the captured with. /// The extra metadata to send with the captured . /// /// The of the successfully captured , or null if it fails. @@ -63,6 +64,7 @@ public async Task CaptureExceptionAsync(Exception exception, SentryMessage message = null, ErrorLevel level = ErrorLevel.Error, IDictionary tags = null, + List fingerprint = null, object extra = null) { JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, @@ -70,6 +72,7 @@ public async Task CaptureExceptionAsync(Exception exception, message, level, tags, + fingerprint, extra); return await SendAsync(packet, CurrentDsn); @@ -82,6 +85,7 @@ public async Task CaptureExceptionAsync(Exception exception, /// The message to capture. /// The of the captured . Default . /// The tags to annotate the captured with. + /// The custom fingerprint to annotate the captured with. /// The extra metadata to send with the captured . /// /// The of the successfully captured , or null if it fails. @@ -89,9 +93,10 @@ public async Task CaptureExceptionAsync(Exception exception, public async Task CaptureMessageAsync(SentryMessage message, ErrorLevel level = ErrorLevel.Info, Dictionary tags = null, + List fingerprint = null, object extra = null) { - JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, message, level, tags, extra); + JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, message, level, tags, fingerprint, extra); return await SendAsync(packet, CurrentDsn); } diff --git a/src/app/SharpRaven/RavenClient.cs b/src/app/SharpRaven/RavenClient.cs index 8a40e7d1..10f64256 100644 --- a/src/app/SharpRaven/RavenClient.cs +++ b/src/app/SharpRaven/RavenClient.cs @@ -2,21 +2,21 @@ // Copyright (c) 2014 The Sentry Team and individual contributors. // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are permitted // provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // 3. Neither the name of the Sentry nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR @@ -199,6 +199,7 @@ public string CaptureException(Exception exception, message, level, tags, + fingerprint, extra); return Send(packet, CurrentDsn); @@ -222,7 +223,7 @@ public string CaptureMessage(SentryMessage message, List fingerprint = null, object extra = null) { - JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, message, level, tags, extra); + JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, message, level, tags, fingerprint, extra); return Send(packet, CurrentDsn); } @@ -359,4 +360,4 @@ private string HandleException(Exception exception) return null; } } -} +} \ No newline at end of file From fce50b36825043940b081463635124fbdc2b90a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 18 Nov 2015 15:47:57 +0100 Subject: [PATCH 115/171] Moved CaptureMessageAsync out of the "Deprecated Methods" region. --- src/app/SharpRaven/IRavenClient.cs | 42 ++++++++++++++---------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/app/SharpRaven/IRavenClient.cs b/src/app/SharpRaven/IRavenClient.cs index 9e7eb8ee..9154c7fc 100644 --- a/src/app/SharpRaven/IRavenClient.cs +++ b/src/app/SharpRaven/IRavenClient.cs @@ -94,7 +94,26 @@ string CaptureException(Exception exception, object extra = null); + /// + /// Captures the message. + /// + /// The message to capture. + /// The of the captured . Default . + /// The tags to annotate the captured with. + /// The custom fingerprint to annotate the captured with. + /// The extra metadata to send with the captured . + /// + /// The of the successfully captured , or null if it fails. + /// + string CaptureMessage(SentryMessage message, + ErrorLevel level = ErrorLevel.Info, + Dictionary tags = null, + List fingerprint = null, + object extra = null); + + #if (!net40) + /// /// Captures the . /// @@ -114,29 +133,7 @@ Task CaptureExceptionAsync(Exception exception, List fingerprint = null, object extra = null); -#endif - - /// - /// Captures the message. - /// - /// The message to capture. - /// The of the captured . Default . - /// The tags to annotate the captured with. - /// The custom fingerprint to annotate the captured with. - /// The extra metadata to send with the captured . - /// - /// The of the successfully captured , or null if it fails. - /// - string CaptureMessage(SentryMessage message, - ErrorLevel level = ErrorLevel.Info, - Dictionary tags = null, - List fingerprint = null, - object extra = null); - - #region Deprecated Methods - -#if (!net40) /// /// Captures the message. /// @@ -155,6 +152,7 @@ Task CaptureMessageAsync(SentryMessage message, object extra = null); #endif + #region Deprecated Methods /// /// Captures the event. From 2f006a1df29be62252a67b5942168e25b794b533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 18 Nov 2015 15:50:39 +0100 Subject: [PATCH 116/171] Added capture test for fingerprint --- .../Integration/CaptureTests.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs b/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs index c7740763..cfc35a55 100644 --- a/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs +++ b/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs @@ -120,6 +120,23 @@ public void CaptureException_Doesnt_Fail_On_Error_During_Send() } + [Test] + public void CaptureException_WithFingerprint_ReturnsValidID() + { + try + { + Helper.FirstLevelException(); + } + catch (Exception exception) + { + var id = this.ravenClient.CaptureException(exception, fingerprint : new[] { "f", "i", "n", "g", "e", "r" }.ToList()); + + Assert.That(id, Is.Not.Null); + Assert.That(Guid.Parse(id), Is.Not.Null); + } + } + + [Test] public void CaptureException_WithMessageFormat_ReturnsValidID() { From 62eda27fa4d8986e66a8a863a83241161500f080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 18 Nov 2015 15:53:07 +0100 Subject: [PATCH 117/171] Change the fingerprint type from List to string[]. --- src/app/SharpRaven/Data/IJsonPacketFactory.cs | 4 ++-- src/app/SharpRaven/Data/JsonPacket.cs | 2 +- src/app/SharpRaven/Data/JsonPacketFactory.cs | 4 ++-- src/app/SharpRaven/IRavenClient.cs | 8 ++++---- src/app/SharpRaven/RavenClient.Net45.cs | 4 ++-- src/app/SharpRaven/RavenClient.cs | 4 ++-- .../SharpRaven.UnitTests/Integration/CaptureTests.cs | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/app/SharpRaven/Data/IJsonPacketFactory.cs b/src/app/SharpRaven/Data/IJsonPacketFactory.cs index a02ea537..b8a1676a 100644 --- a/src/app/SharpRaven/Data/IJsonPacketFactory.cs +++ b/src/app/SharpRaven/Data/IJsonPacketFactory.cs @@ -61,7 +61,7 @@ JsonPacket Create(string project, SentryMessage message, ErrorLevel level = ErrorLevel.Info, IDictionary tags = null, - List fingerprint = null, + string[] fingerprint = null, object extra = null); @@ -91,7 +91,7 @@ JsonPacket Create(string project, SentryMessage message = null, ErrorLevel level = ErrorLevel.Error, IDictionary tags = null, - List fingerprint = null, + string[] fingerprint = null, object extra = null); } } diff --git a/src/app/SharpRaven/Data/JsonPacket.cs b/src/app/SharpRaven/Data/JsonPacket.cs index 45b7ae4e..74f4a4b6 100644 --- a/src/app/SharpRaven/Data/JsonPacket.cs +++ b/src/app/SharpRaven/Data/JsonPacket.cs @@ -250,7 +250,7 @@ private JsonPacket() /// Gets or sets the fingerprint used for custom grouping /// [JsonProperty(PropertyName = "fingerprint", NullValueHandling = NullValueHandling.Ignore)] - public List Fingerprint { get; set; } + public string[] Fingerprint { get; set; } /// /// A map or list of tags for this event. diff --git a/src/app/SharpRaven/Data/JsonPacketFactory.cs b/src/app/SharpRaven/Data/JsonPacketFactory.cs index 5846cf1a..d391ad11 100644 --- a/src/app/SharpRaven/Data/JsonPacketFactory.cs +++ b/src/app/SharpRaven/Data/JsonPacketFactory.cs @@ -57,7 +57,7 @@ public JsonPacket Create(string project, SentryMessage message, ErrorLevel level = ErrorLevel.Info, IDictionary tags = null, - List fingerprint = null, + string[] fingerprint = null, object extra = null) { var json = new JsonPacket(project) @@ -100,7 +100,7 @@ public JsonPacket Create(string project, SentryMessage message = null, ErrorLevel level = ErrorLevel.Error, IDictionary tags = null, - List fingerprint = null, + string[] fingerprint = null, object extra = null) { var json = new JsonPacket(project, exception) diff --git a/src/app/SharpRaven/IRavenClient.cs b/src/app/SharpRaven/IRavenClient.cs index 9154c7fc..6028c58e 100644 --- a/src/app/SharpRaven/IRavenClient.cs +++ b/src/app/SharpRaven/IRavenClient.cs @@ -90,7 +90,7 @@ string CaptureException(Exception exception, SentryMessage message = null, ErrorLevel level = ErrorLevel.Error, IDictionary tags = null, - List fingerprint = null, + string[] fingerprint = null, object extra = null); @@ -108,7 +108,7 @@ string CaptureException(Exception exception, string CaptureMessage(SentryMessage message, ErrorLevel level = ErrorLevel.Info, Dictionary tags = null, - List fingerprint = null, + string[] fingerprint = null, object extra = null); @@ -130,7 +130,7 @@ Task CaptureExceptionAsync(Exception exception, SentryMessage message = null, ErrorLevel level = ErrorLevel.Error, IDictionary tags = null, - List fingerprint = null, + string[] fingerprint = null, object extra = null); @@ -148,7 +148,7 @@ Task CaptureExceptionAsync(Exception exception, Task CaptureMessageAsync(SentryMessage message, ErrorLevel level = ErrorLevel.Info, Dictionary tags = null, - List fingerprint = null, + string[] fingerprint = null, object extra = null); #endif diff --git a/src/app/SharpRaven/RavenClient.Net45.cs b/src/app/SharpRaven/RavenClient.Net45.cs index ec6bc8ba..a92ad243 100644 --- a/src/app/SharpRaven/RavenClient.Net45.cs +++ b/src/app/SharpRaven/RavenClient.Net45.cs @@ -64,7 +64,7 @@ public async Task CaptureExceptionAsync(Exception exception, SentryMessage message = null, ErrorLevel level = ErrorLevel.Error, IDictionary tags = null, - List fingerprint = null, + string[] fingerprint = null, object extra = null) { JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, @@ -93,7 +93,7 @@ public async Task CaptureExceptionAsync(Exception exception, public async Task CaptureMessageAsync(SentryMessage message, ErrorLevel level = ErrorLevel.Info, Dictionary tags = null, - List fingerprint = null, + string[] fingerprint = null, object extra = null) { JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, message, level, tags, fingerprint, extra); diff --git a/src/app/SharpRaven/RavenClient.cs b/src/app/SharpRaven/RavenClient.cs index 10f64256..fd572728 100644 --- a/src/app/SharpRaven/RavenClient.cs +++ b/src/app/SharpRaven/RavenClient.cs @@ -191,7 +191,7 @@ public string CaptureException(Exception exception, SentryMessage message = null, ErrorLevel level = ErrorLevel.Error, IDictionary tags = null, - List fingerprint = null, + string[] fingerprint = null, object extra = null) { JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, @@ -220,7 +220,7 @@ public string CaptureException(Exception exception, public string CaptureMessage(SentryMessage message, ErrorLevel level = ErrorLevel.Info, Dictionary tags = null, - List fingerprint = null, + string[] fingerprint = null, object extra = null) { JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, message, level, tags, fingerprint, extra); diff --git a/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs b/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs index cfc35a55..7be3f7a6 100644 --- a/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs +++ b/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs @@ -129,7 +129,7 @@ public void CaptureException_WithFingerprint_ReturnsValidID() } catch (Exception exception) { - var id = this.ravenClient.CaptureException(exception, fingerprint : new[] { "f", "i", "n", "g", "e", "r" }.ToList()); + var id = this.ravenClient.CaptureException(exception, fingerprint : new[] { "f", "i", "n", "g", "e", "r" }); Assert.That(id, Is.Not.Null); Assert.That(Guid.Parse(id), Is.Not.Null); From 8fa8d80eb6626db370f98b6e20c7fab3b306c526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 18 Nov 2015 16:22:39 +0100 Subject: [PATCH 118/171] Added async capture tests --- .../Integration/CaptureAsyncTests.cs | 244 ++++++++++++++++++ .../Integration/CaptureTests.cs | 44 ---- .../Integration/Helper.cs | 93 +++++++ .../SharpRaven.UnitTests.csproj | 2 + 4 files changed, 339 insertions(+), 44 deletions(-) create mode 100644 src/tests/SharpRaven.UnitTests/Integration/CaptureAsyncTests.cs create mode 100644 src/tests/SharpRaven.UnitTests/Integration/Helper.cs diff --git a/src/tests/SharpRaven.UnitTests/Integration/CaptureAsyncTests.cs b/src/tests/SharpRaven.UnitTests/Integration/CaptureAsyncTests.cs new file mode 100644 index 00000000..ecfc3226 --- /dev/null +++ b/src/tests/SharpRaven.UnitTests/Integration/CaptureAsyncTests.cs @@ -0,0 +1,244 @@ +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; + +using NUnit.Framework; + +using SharpRaven.Data; +using SharpRaven.Logging; + +namespace SharpRaven.UnitTests.Integration +{ + [TestFixture] + public class CaptureAsyncTests + { + #region SetUp/Teardown + + [SetUp] + public void Setup() + { + Console.WriteLine("Initializing RavenClient."); + this.ravenClient = new RavenClient(DsnUrl) + { + Logger = "C#", + LogScrubber = new LogScrubber() + }; + + Helper.PrintInfo("Sentry Uri: " + this.ravenClient.CurrentDsn.SentryUri); + Helper.PrintInfo("Port: " + this.ravenClient.CurrentDsn.Port); + Helper.PrintInfo("Public Key: " + this.ravenClient.CurrentDsn.PublicKey); + Helper.PrintInfo("Private Key: " + this.ravenClient.CurrentDsn.PrivateKey); + Helper.PrintInfo("Project ID: " + this.ravenClient.CurrentDsn.ProjectID); + } + + #endregion + + [Test] + public async void CaptureExceptionAsync_CanLogException_If_Send_Fails() + { + const string dsnUri = "http://a:b@totally.notexisting.xyz/666"; + + Exception hookedException = null; + + this.ravenClient = new RavenClient(dsnUri) + { + ErrorOnCapture = exp => hookedException = exp + }; + + Helper.PrintInfo("In test client change!"); + Helper.PrintInfo("Sentry Uri: " + this.ravenClient.CurrentDsn.SentryUri); + Helper.PrintInfo("Port: " + this.ravenClient.CurrentDsn.Port); + Helper.PrintInfo("Public Key: " + this.ravenClient.CurrentDsn.PublicKey); + Helper.PrintInfo("Private Key: " + this.ravenClient.CurrentDsn.PrivateKey); + Helper.PrintInfo("Project ID: " + this.ravenClient.CurrentDsn.ProjectID); + + await this.ravenClient.CaptureExceptionAsync(Helper.GetException()); + + Assert.That(hookedException, Is.Not.Null); + } + + + [Test] + public async void CaptureExceptionAsync_Doesnt_Fail_On_Error_During_Send() + { + const string dsnUri = "http://a:b@totally.notexisting.xyz/666"; + + this.ravenClient = new RavenClient(dsnUri); + + Helper.PrintInfo("In test client change!"); + Helper.PrintInfo("Sentry Uri: " + this.ravenClient.CurrentDsn.SentryUri); + Helper.PrintInfo("Port: " + this.ravenClient.CurrentDsn.Port); + Helper.PrintInfo("Public Key: " + this.ravenClient.CurrentDsn.PublicKey); + Helper.PrintInfo("Private Key: " + this.ravenClient.CurrentDsn.PrivateKey); + Helper.PrintInfo("Project ID: " + this.ravenClient.CurrentDsn.ProjectID); + + await this.ravenClient.CaptureExceptionAsync(Helper.GetException()); + } + + + [Test] + public async void CaptureExceptionAsync_WithFingerprint_ReturnsValidID() + { + var id = await this.ravenClient.CaptureExceptionAsync(Helper.GetException(), + fingerprint : new[] { "f", "i", "n", "g", "e", "r" }); + Assert.That(id, Is.Not.Null); + Assert.That(Guid.Parse(id), Is.Not.Null); + } + + + [Test] + public async void CaptureExceptionAsync_WithMessageFormat_ReturnsValidID() + { + var args = Enumerable.Range(0, 5).Select(i => Guid.NewGuid()).Cast().ToArray(); + var message = new SentryMessage("A {0:N} B {1:N} C {2:N} D {3:N} F {4:N}.", args); + var id = await this.ravenClient.CaptureExceptionAsync(new Exception("Test without a stacktrace."), message); + //Console.WriteLine("Sent packet: " + id); + + Assert.That(id, Is.Not.Null); + Assert.That(Guid.Parse(id), Is.Not.Null); + } + + + [Test] + public async void CaptureExceptionAsync_WithoutStacktrace_ReturnsValidID() + { + var id = await this.ravenClient.CaptureExceptionAsync(new Exception("Test without a stacktrace.")); + //Console.WriteLine("Sent packet: " + id); + + Assert.That(id, Is.Not.Null.Or.Empty); + Assert.That(Guid.Parse(id), Is.Not.Null); + } + + + [Test] + public async void CaptureExceptionAsync_WithStacktrace_ReturnsValidID() + { + var tags = new Dictionary(); + var extra = new Dictionary(); + + tags["TAG"] = "TAG1"; + extra["extra"] = "EXTRA1"; + + var id = await this.ravenClient.CaptureExceptionAsync(Helper.GetException(), tags : tags, extra : extra); + + //Console.WriteLine("Sent packet: " + id); + + Assert.That(id, Is.Not.Null); + Assert.That(Guid.Parse(id), Is.Not.Null); + } + + + [Test] + public async void CaptureMessageAsync_CanLogException_If_Send_Fails() + { + const string dsnUri = "http://a:b@totally.notexisting.xyz/666"; + + Exception hookedException = null; + + this.ravenClient = new RavenClient(dsnUri) + { + ErrorOnCapture = exp => hookedException = exp + }; + + Helper.PrintInfo("In test client change!"); + Helper.PrintInfo("Sentry Uri: " + this.ravenClient.CurrentDsn.SentryUri); + Helper.PrintInfo("Port: " + this.ravenClient.CurrentDsn.Port); + Helper.PrintInfo("Public Key: " + this.ravenClient.CurrentDsn.PublicKey); + Helper.PrintInfo("Private Key: " + this.ravenClient.CurrentDsn.PrivateKey); + Helper.PrintInfo("Project ID: " + this.ravenClient.CurrentDsn.ProjectID); + + await this.ravenClient.CaptureMessageAsync("Test message"); + + Assert.NotNull(hookedException); + } + + + [Test] + public async void CaptureMessageAsync_Doesnt_Fail_On_Error_During_Send() + { + const string dsnUri = "http://a:b@totally.notexisting.xyz/666"; + + this.ravenClient = new RavenClient(dsnUri); + + Helper.PrintInfo("In test client change!"); + Helper.PrintInfo("Sentry Uri: " + this.ravenClient.CurrentDsn.SentryUri); + Helper.PrintInfo("Port: " + this.ravenClient.CurrentDsn.Port); + Helper.PrintInfo("Public Key: " + this.ravenClient.CurrentDsn.PublicKey); + Helper.PrintInfo("Private Key: " + this.ravenClient.CurrentDsn.PrivateKey); + Helper.PrintInfo("Project ID: " + this.ravenClient.CurrentDsn.ProjectID); + + await this.ravenClient.CaptureMessageAsync("Test message"); + } + + + [Test] + public async void CaptureMessageAsync_ReturnsValidID() + { + var id = await this.ravenClient.CaptureMessageAsync("Test"); + //Console.WriteLine("Sent packet: " + id); + + Assert.That(id, Is.Not.Null); + Assert.That(Guid.Parse(id), Is.Not.Null); + } + + + [Test] + public async void CaptureMessageAsync_WithCompression_ReturnsValidID() + { + this.ravenClient.Compression = true; + var id = await this.ravenClient.CaptureExceptionAsync(new Exception("Test without a stacktrace.")); + + Assert.That(id, Is.Not.Null); + Assert.That(Guid.Parse(id), Is.Not.Null); + } + + + [Test] + public async void CaptureMessageAsync_WithFormat_ReturnsValidID() + { + var args = Enumerable.Range(0, 5).Select(i => Guid.NewGuid()).Cast().ToArray(); + var message = new SentryMessage("Lorem %s ipsum %s dolor %s sit %s amet %s.", args); + var id = await this.ravenClient.CaptureMessageAsync(message); + //Console.WriteLine("Sent packet: " + id); + + Assert.That(id, Is.Not.Null); + Assert.That(Guid.Parse(id), Is.Not.Null); + } + + + private const string DsnUrl = + "https://7d6466e66155431495bdb4036ba9a04b:4c1cfeab7ebd4c1cb9e18008173a3630@app.getsentry.com/3739"; + + private IRavenClient ravenClient; + } +} \ No newline at end of file diff --git a/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs b/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs index 7be3f7a6..f9cff17e 100644 --- a/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs +++ b/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs @@ -269,49 +269,5 @@ public void CaptureMessage_WithFormat_ReturnsValidID() "https://7d6466e66155431495bdb4036ba9a04b:4c1cfeab7ebd4c1cb9e18008173a3630@app.getsentry.com/3739"; private IRavenClient ravenClient; - - private static class Helper - { - public static void FirstLevelException() - { - try - { - SecondLevelException(); - } - catch (Exception e) - { - throw new Exception("First Level Exception", e); - } - } - - - public static void PrintInfo(string info) - { - Console.ForegroundColor = ConsoleColor.Green; - Console.Write("[INFO] "); - Console.ForegroundColor = ConsoleColor.Gray; - Console.WriteLine(info); - } - - - private static void PerformDivideByZero() - { - int i2 = 0; - int i = 10 / i2; - } - - - private static void SecondLevelException() - { - try - { - PerformDivideByZero(); - } - catch (Exception e) - { - throw new InvalidOperationException("Second Level Exception", e); - } - } - } } } \ No newline at end of file diff --git a/src/tests/SharpRaven.UnitTests/Integration/Helper.cs b/src/tests/SharpRaven.UnitTests/Integration/Helper.cs new file mode 100644 index 00000000..594ba17d --- /dev/null +++ b/src/tests/SharpRaven.UnitTests/Integration/Helper.cs @@ -0,0 +1,93 @@ +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; + +namespace SharpRaven.UnitTests.Integration +{ + public static class Helper + { + public static void FirstLevelException() + { + try + { + SecondLevelException(); + } + catch (Exception e) + { + throw new Exception("First Level Exception", e); + } + } + + + public static Exception GetException() + { + try + { + FirstLevelException(); + } + catch (Exception exception) + { + return exception; + } + + return null; + } + + + public static void PrintInfo(string info) + { + Console.ForegroundColor = ConsoleColor.Green; + Console.Write("[INFO] "); + Console.ForegroundColor = ConsoleColor.Gray; + Console.WriteLine(info); + } + + + private static void PerformDivideByZero() + { + int i2 = 0; + int i = 10 / i2; + } + + + private static void SecondLevelException() + { + try + { + PerformDivideByZero(); + } + catch (Exception e) + { + throw new InvalidOperationException("Second Level Exception", e); + } + } + } +} \ No newline at end of file diff --git a/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj b/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj index 268a1efc..d006c56b 100644 --- a/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj +++ b/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj @@ -84,6 +84,8 @@ + + From ffa01264b55efd651fbc00db8404e57eb0850d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Thu, 19 Nov 2015 12:27:01 +0100 Subject: [PATCH 119/171] Wrap .NET 4.5 stuff in #region --- src/app/SharpRaven/RavenClient.Net45.cs | 3 ++- .../SharpRaven.UnitTests/Integration/CaptureAsyncTests.cs | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/app/SharpRaven/RavenClient.Net45.cs b/src/app/SharpRaven/RavenClient.Net45.cs index a92ad243..205a5317 100644 --- a/src/app/SharpRaven/RavenClient.Net45.cs +++ b/src/app/SharpRaven/RavenClient.Net45.cs @@ -28,13 +28,14 @@ #endregion +#if !(net40) + using System.IO; using System.Net; using Newtonsoft.Json; using SharpRaven.Utilities; -#if !(net40) using System; using System.Collections.Generic; using System.Threading.Tasks; diff --git a/src/tests/SharpRaven.UnitTests/Integration/CaptureAsyncTests.cs b/src/tests/SharpRaven.UnitTests/Integration/CaptureAsyncTests.cs index ecfc3226..c1eb21ae 100644 --- a/src/tests/SharpRaven.UnitTests/Integration/CaptureAsyncTests.cs +++ b/src/tests/SharpRaven.UnitTests/Integration/CaptureAsyncTests.cs @@ -28,6 +28,8 @@ #endregion +#if !(net40) + using System; using System.Collections.Generic; using System.Linq; @@ -241,4 +243,6 @@ public async void CaptureMessageAsync_WithFormat_ReturnsValidID() private IRavenClient ravenClient; } -} \ No newline at end of file +} + +#endif \ No newline at end of file From 4e03ae44d80166f212117063e5a63b061ea9b0f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Thu, 19 Nov 2015 12:34:22 +0100 Subject: [PATCH 120/171] Added build status badge to readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bf9101bb..1ee8706a 100644 --- a/README.md +++ b/README.md @@ -47,8 +47,8 @@ You can clone and build SharpRaven yourself, but for those of us who are happy w Resources --------- -* [Build Status](http://teamcity.codebetter.com/project.html?projectId=project344&tab=projectOverview) (requires registration) +* [![Build Status](http://teamcity.codebetter.com/app/rest/builds/buildType:(id:bt1000)/statusIcon)](http://teamcity.codebetter.com/viewType.html?buildTypeId=bt1000&guest=1) +* [![Join the chat at https://gitter.im/getsentry/raven-csharp](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/getsentry/raven-csharp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) * [Code](http://github.com/getsentry/raven-csharp) * [Mailing List](https://groups.google.com/group/getsentry) -* [IRC](irc://irc.freenode.net/sentry) (irc.freenode.net, #sentry) -* [![Join the chat at https://gitter.im/getsentry/raven-csharp](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/getsentry/raven-csharp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) \ No newline at end of file +* [IRC](irc://irc.freenode.net/sentry) (irc.freenode.net, #sentry) \ No newline at end of file From bf275fdcb4f7eca730cdd9032cfa45f8e5ae06c9 Mon Sep 17 00:00:00 2001 From: Jakub Malczak Date: Fri, 20 Nov 2015 01:06:38 +0900 Subject: [PATCH 121/171] Fixed compilation issue, removed Exception.Data integration tests and created some tests in JsonPacketFactory, fixed UniqueKey method --- .gitignore | 1 + src/app/SharpRaven/Data/JsonPacketFactory.cs | 7 ++-- .../Data/JsonPacketFactoryTests.cs | 36 ++++++++++++++++++- .../Integration/CaptureTests.cs | 31 ---------------- 4 files changed, 40 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index 799cb236..165f4dfe 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ obj/ !/src/packages/repositories.config /TestResult.xml docs/_build +.vs diff --git a/src/app/SharpRaven/Data/JsonPacketFactory.cs b/src/app/SharpRaven/Data/JsonPacketFactory.cs index 21b34d48..b495aa17 100644 --- a/src/app/SharpRaven/Data/JsonPacketFactory.cs +++ b/src/app/SharpRaven/Data/JsonPacketFactory.cs @@ -31,6 +31,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Reflection; namespace SharpRaven.Data { @@ -139,7 +140,7 @@ private static IDictionary Convert(object extra, IDictionary dat { try { - var value = property.GetValue(extra); + var value = property.GetValue(extra, BindingFlags.Default, null, null, null); var key = UniqueKey(result, property.Name); result.Add(key, value); } @@ -180,9 +181,9 @@ private static string UniqueKey(IDictionary dictionary, object k for (var i = 0; i < 10000; i++) { - var newKey = String.Join(stringKey, i); + var newKey = String.Concat(stringKey, i); if (!dictionary.ContainsKey(newKey)) - return stringKey; + return newKey; } throw new ArgumentException(String.Format("Unable to find a unique key for '{0}'.", stringKey), "key"); diff --git a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs index b362193e..27bb6edc 100644 --- a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs +++ b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs @@ -29,6 +29,7 @@ #endregion using System; +using System.Collections.Generic; using NUnit.Framework; @@ -142,7 +143,6 @@ public void Create_ProjectAndException_ProjectIsEqual() Assert.That(json.Project, Is.EqualTo(project)); } - [Test] public void Create_ProjectAndException_ServerNameEqualsMachineName() { @@ -152,6 +152,40 @@ public void Create_ProjectAndException_ServerNameEqualsMachineName() Assert.That(json.ServerName, Is.EqualTo(Environment.MachineName)); } + [Test] + public void Create_ProjectAndException_DataPropertyIsSavedInExtras() + { + var project = Guid.NewGuid().ToString(); + var exception = new Exception("Error"); + exception.Data.Add("key", "value"); + var json = this.jsonPacketFactory.Create(project, exception); + + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); + } + + [Test] + public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtrasObject() + { + var project = Guid.NewGuid().ToString(); + var exception = new Exception("Error"); + exception.Data.Add("key", "value"); + var json = this.jsonPacketFactory.Create(project, exception, extra: new { key2 = "value2" }); + + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key2", "value2"))); + } + + [Test] + public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtrasObjectEvenWithTheSameKey() + { + var project = Guid.NewGuid().ToString(); + var exception = new Exception("Error"); + exception.Data.Add("key", "value"); + var json = this.jsonPacketFactory.Create(project, exception, extra: new { key = "value" }); + + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key0", "value"))); + } private IJsonPacketFactory jsonPacketFactory; diff --git a/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs b/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs index b79b3b94..05920bc8 100644 --- a/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs +++ b/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs @@ -32,8 +32,6 @@ using System.Collections.Generic; using System.Linq; -using NSubstitute; - using NUnit.Framework; using SharpRaven.Data; @@ -121,35 +119,6 @@ public void CaptureException_Doesnt_Fail_On_Error_During_Send() } } - - [Test] - public void CaptureException_WithData_DataIsCaptured() - { - var data = new KeyValuePair("DataKey", Guid.NewGuid().ToString("N")); - - try - { - Helper.FirstLevelException(data); - } - catch (Exception e) - { - // I don't feel OK using LogScrubber for testing this, but we can't test at a (mocked) HTTP level yet. @asbjornu - var logScrubber = Substitute.For(); - - this.ravenClient = new RavenClient(DsnUrl) - { - Logger = "C#", - LogScrubber = logScrubber - }; - - this.ravenClient.CaptureException(e); - - logScrubber.Received(1) - .Scrub(Arg.Is(s => s.Contains(String.Format("\"{0}\":\"{1}\"", data.Key, data.Value)))); - } - } - - [Test] public void CaptureException_WithMessageFormat_ReturnsValidID() { From 3ffc98a6f3652b00f97b35cee03cdfead44d1945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 20 Nov 2015 16:12:54 +0100 Subject: [PATCH 122/171] R# cleanup --- .../Data/JsonPacketFactoryTests.cs | 71 ++++++++++--------- .../Integration/CaptureTests.cs | 1 + 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs index 27bb6edc..e89e6dd9 100644 --- a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs +++ b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs @@ -103,90 +103,95 @@ public void Create_Project_ServerNameEqualsMachineName() [Test] - public void Create_ProjectAndException_EventIDIsValidGuid() + public void Create_ProjectAndException_DataPropertyIsSavedInExtras() { var project = Guid.NewGuid().ToString(); - var json = this.jsonPacketFactory.Create(project, new Exception("Error")); + var exception = new Exception("Error"); + exception.Data.Add("key", "value"); + var json = this.jsonPacketFactory.Create(project, exception); - Assert.That(json.EventID, Is.Not.Null.Or.Empty, "EventID"); - Assert.That(Guid.Parse(json.EventID), Is.Not.Null); + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); } [Test] - public void Create_ProjectAndException_MessageEqualsExceptionMessage() + public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtrasObject() { var project = Guid.NewGuid().ToString(); - Exception exception = new Exception("Error"); - var json = this.jsonPacketFactory.Create(project, exception); + var exception = new Exception("Error"); + exception.Data.Add("key", "value"); + var json = this.jsonPacketFactory.Create(project, exception, extra : new { key2 = "value2" }); - Assert.That(json.Message, Is.EqualTo(exception.Message)); + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key2", "value2"))); } [Test] - public void Create_ProjectAndException_ModulesHasCountGreaterThanZero() + public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtrasObjectEvenWithTheSameKey() { var project = Guid.NewGuid().ToString(); - var json = this.jsonPacketFactory.Create(project, new Exception("Error")); + var exception = new Exception("Error"); + exception.Data.Add("key", "value"); + var json = this.jsonPacketFactory.Create(project, exception, extra : new { key = "value" }); - Assert.That(json.Modules, Has.Count.GreaterThan(0)); + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key0", "value"))); } [Test] - public void Create_ProjectAndException_ProjectIsEqual() + public void Create_ProjectAndException_EventIDIsValidGuid() { var project = Guid.NewGuid().ToString(); var json = this.jsonPacketFactory.Create(project, new Exception("Error")); - Assert.That(json.Project, Is.EqualTo(project)); + Assert.That(json.EventID, Is.Not.Null.Or.Empty, "EventID"); + Assert.That(Guid.Parse(json.EventID), Is.Not.Null); } + [Test] - public void Create_ProjectAndException_ServerNameEqualsMachineName() + public void Create_ProjectAndException_MessageEqualsExceptionMessage() { var project = Guid.NewGuid().ToString(); - var json = this.jsonPacketFactory.Create(project, new Exception("Error")); + Exception exception = new Exception("Error"); + var json = this.jsonPacketFactory.Create(project, exception); - Assert.That(json.ServerName, Is.EqualTo(Environment.MachineName)); + Assert.That(json.Message, Is.EqualTo(exception.Message)); } + [Test] - public void Create_ProjectAndException_DataPropertyIsSavedInExtras() + public void Create_ProjectAndException_ModulesHasCountGreaterThanZero() { var project = Guid.NewGuid().ToString(); - var exception = new Exception("Error"); - exception.Data.Add("key", "value"); - var json = this.jsonPacketFactory.Create(project, exception); + var json = this.jsonPacketFactory.Create(project, new Exception("Error")); - Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); + Assert.That(json.Modules, Has.Count.GreaterThan(0)); } + [Test] - public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtrasObject() + public void Create_ProjectAndException_ProjectIsEqual() { var project = Guid.NewGuid().ToString(); - var exception = new Exception("Error"); - exception.Data.Add("key", "value"); - var json = this.jsonPacketFactory.Create(project, exception, extra: new { key2 = "value2" }); + var json = this.jsonPacketFactory.Create(project, new Exception("Error")); - Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); - Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key2", "value2"))); + Assert.That(json.Project, Is.EqualTo(project)); } + [Test] - public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtrasObjectEvenWithTheSameKey() + public void Create_ProjectAndException_ServerNameEqualsMachineName() { var project = Guid.NewGuid().ToString(); - var exception = new Exception("Error"); - exception.Data.Add("key", "value"); - var json = this.jsonPacketFactory.Create(project, exception, extra: new { key = "value" }); + var json = this.jsonPacketFactory.Create(project, new Exception("Error")); - Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); - Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key0", "value"))); + Assert.That(json.ServerName, Is.EqualTo(Environment.MachineName)); } + private IJsonPacketFactory jsonPacketFactory; private class TestableJsonPacketFactory : JsonPacketFactory diff --git a/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs b/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs index 3f25195b..f9cff17e 100644 --- a/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs +++ b/src/tests/SharpRaven.UnitTests/Integration/CaptureTests.cs @@ -119,6 +119,7 @@ public void CaptureException_Doesnt_Fail_On_Error_During_Send() } } + [Test] public void CaptureException_WithFingerprint_ReturnsValidID() { From 5db91c495b162b43a1d5be64e761c5ea6420b797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 20 Nov 2015 16:36:31 +0100 Subject: [PATCH 123/171] Moved Helper up a folder for more reuse --- src/tests/SharpRaven.UnitTests/{Integration => }/Helper.cs | 2 +- src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/tests/SharpRaven.UnitTests/{Integration => }/Helper.cs (98%) diff --git a/src/tests/SharpRaven.UnitTests/Integration/Helper.cs b/src/tests/SharpRaven.UnitTests/Helper.cs similarity index 98% rename from src/tests/SharpRaven.UnitTests/Integration/Helper.cs rename to src/tests/SharpRaven.UnitTests/Helper.cs index 594ba17d..cdb7078f 100644 --- a/src/tests/SharpRaven.UnitTests/Integration/Helper.cs +++ b/src/tests/SharpRaven.UnitTests/Helper.cs @@ -30,7 +30,7 @@ using System; -namespace SharpRaven.UnitTests.Integration +namespace SharpRaven.UnitTests { public static class Helper { diff --git a/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj b/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj index d006c56b..371555b0 100644 --- a/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj +++ b/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj @@ -85,7 +85,7 @@ - + From 75c984c0d742ae3dcbc27f2f1710cdd11872ad40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 20 Nov 2015 17:09:05 +0100 Subject: [PATCH 124/171] Added ExceptionData class, to be able to capture nested exception data. Adjusted existing Exception.Data tests and added a new one explicitly testing the nesting. --- src/app/SharpRaven/Data/ExceptionData.cs | 84 +++++++++++++++++++ src/app/SharpRaven/Data/JsonPacketFactory.cs | 76 +++++++---------- src/app/SharpRaven/SharpRaven.csproj | 1 + .../Data/JsonPacketFactoryTests.cs | 55 ++++++++---- src/tests/SharpRaven.UnitTests/Helper.cs | 12 ++- 5 files changed, 168 insertions(+), 60 deletions(-) create mode 100644 src/app/SharpRaven/Data/ExceptionData.cs diff --git a/src/app/SharpRaven/Data/ExceptionData.cs b/src/app/SharpRaven/Data/ExceptionData.cs new file mode 100644 index 00000000..d93c9931 --- /dev/null +++ b/src/app/SharpRaven/Data/ExceptionData.cs @@ -0,0 +1,84 @@ +#region License + +// Copyright (c) 2014 The Sentry Team and individual contributors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// 3. Neither the name of the Sentry nor the names of its contributors may be used to +// endorse or promote products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; + +namespace SharpRaven.Data +{ + /// + /// Data class for containing . + /// + public class ExceptionData : Dictionary + { + private readonly Exception exception; + + + /// Initializes a new instance of the class. + /// The exception. + public ExceptionData(Exception exception) + { + if (exception == null) + throw new ArgumentNullException("exception"); + + this.exception = exception; + + foreach (var k in exception.Data.Keys) + { + try + { + var value = exception.Data[k]; + var key = JsonPacketFactory.UniqueKey(this, k); + Add(key, value); + } + catch (Exception e) + { + Console.WriteLine("ERROR: " + e); + } + } + + if (exception.InnerException == null) + return; + + var exceptionData = new ExceptionData(exception.InnerException); + exceptionData.AddTo(this); + } + + + /// Adds the current instance to the specified . + /// The dictionary to current instance to. + public void AddTo(IDictionary dictionary) + { + var key = String.Concat(this.exception.GetType().Name, "Data"); + key = JsonPacketFactory.UniqueKey(dictionary, key); + dictionary.Add(key, this); + } + } +} \ No newline at end of file diff --git a/src/app/SharpRaven/Data/JsonPacketFactory.cs b/src/app/SharpRaven/Data/JsonPacketFactory.cs index 54d7086e..c66a6b26 100644 --- a/src/app/SharpRaven/Data/JsonPacketFactory.cs +++ b/src/app/SharpRaven/Data/JsonPacketFactory.cs @@ -2,21 +2,21 @@ // Copyright (c) 2014 The Sentry Team and individual contributors. // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are permitted // provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // 3. Neither the name of the Sentry nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR @@ -29,7 +29,6 @@ #endregion using System; -using System.Collections; using System.Collections.Generic; using System.Reflection; @@ -112,7 +111,7 @@ public JsonPacket Create(string project, Level = level, Tags = tags, Fingerprint = fingerprint, - Extra = Convert(extra, exception.Data) + Extra = Convert(extra, exception) }; return OnCreate(json); @@ -133,9 +132,27 @@ protected virtual JsonPacket OnCreate(JsonPacket jsonPacket) } - private static IDictionary Convert(object extra, IDictionary data = null) + internal static string UniqueKey(IDictionary dictionary, object key) { - if (data == null && extra == null) + var stringKey = key as string ?? key.ToString(); + + if (!dictionary.ContainsKey(stringKey)) + return stringKey; + + for (var i = 0; i < 10000; i++) + { + var newKey = String.Concat(stringKey, i); + if (!dictionary.ContainsKey(newKey)) + return newKey; + } + + throw new ArgumentException(String.Format("Unable to find a unique key for '{0}'.", stringKey), "key"); + } + + + private static IDictionary Convert(object extra, Exception exception = null) + { + if (exception == null && extra == null) return null; var result = new Dictionary(); @@ -150,49 +167,20 @@ private static IDictionary Convert(object extra, IDictionary dat var key = UniqueKey(result, property.Name); result.Add(key, value); } - catch (Exception exception) + catch (Exception e) { - Console.WriteLine("ERROR: " + exception); + Console.WriteLine("ERROR: " + e); } } } - if (data == null) + if (exception == null) return result; - foreach (var k in data.Keys) - { - try - { - var value = data[k]; - var key = UniqueKey(result, k); - result.Add(key, value); - } - catch (Exception exception) - { - Console.WriteLine("ERROR: " + exception); - } - } + var exceptionData = new ExceptionData(exception); + exceptionData.AddTo(result); return result; } - - - private static string UniqueKey(IDictionary dictionary, object key) - { - var stringKey = key as string ?? key.ToString(); - - if (!dictionary.ContainsKey(stringKey)) - return stringKey; - - for (var i = 0; i < 10000; i++) - { - var newKey = String.Concat(stringKey, i); - if (!dictionary.ContainsKey(newKey)) - return newKey; - } - - throw new ArgumentException(String.Format("Unable to find a unique key for '{0}'.", stringKey), "key"); - } } -} +} \ No newline at end of file diff --git a/src/app/SharpRaven/SharpRaven.csproj b/src/app/SharpRaven/SharpRaven.csproj index a1983e14..ce4355a7 100644 --- a/src/app/SharpRaven/SharpRaven.csproj +++ b/src/app/SharpRaven/SharpRaven.csproj @@ -78,6 +78,7 @@ Properties\CommonAssemblyInfo.cs + diff --git a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs index e89e6dd9..64572712 100644 --- a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs +++ b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs @@ -31,6 +31,8 @@ using System; using System.Collections.Generic; +using Newtonsoft.Json; + using NUnit.Framework; using SharpRaven.Data; @@ -110,7 +112,9 @@ public void Create_ProjectAndException_DataPropertyIsSavedInExtras() exception.Data.Add("key", "value"); var json = this.jsonPacketFactory.Create(project, exception); - Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); + Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData")); + Assert.That(json.Extra["ExceptionData"], Is.TypeOf()); + Assert.That(json.Extra["ExceptionData"], Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); } @@ -122,23 +126,13 @@ public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtra exception.Data.Add("key", "value"); var json = this.jsonPacketFactory.Create(project, exception, extra : new { key2 = "value2" }); - Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key2", "value2"))); + Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData")); + Assert.That(json.Extra["ExceptionData"], Is.TypeOf()); + Assert.That(json.Extra["ExceptionData"], Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); } - [Test] - public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtrasObjectEvenWithTheSameKey() - { - var project = Guid.NewGuid().ToString(); - var exception = new Exception("Error"); - exception.Data.Add("key", "value"); - var json = this.jsonPacketFactory.Create(project, exception, extra : new { key = "value" }); - - Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); - Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key0", "value"))); - } - [Test] public void Create_ProjectAndException_EventIDIsValidGuid() @@ -172,6 +166,39 @@ public void Create_ProjectAndException_ModulesHasCountGreaterThanZero() } + [Test] + public void Create_ProjectAndException_NestedExceptionsAndExtraAreStoredInExtrasObject() + { + var project = Guid.NewGuid().ToString(); + var exception = Helper.GetException(); + var json = this.jsonPacketFactory.Create(project, exception, extra : new { ExtraKey = "ExtraValue" }); + + var s = JsonConvert.SerializeObject(json, Formatting.Indented); + + Console.WriteLine(s); + + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("ExtraKey", "ExtraValue"))); + Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData")); + Assert.That(json.Extra["ExceptionData"], Is.TypeOf()); + + var exceptionData = (ExceptionData)json.Extra["ExceptionData"]; + Assert.That(exceptionData, + Has.Exactly(1).EqualTo(new KeyValuePair("FirstLevelExceptionKey", "FirstLevelExceptionValue"))); + Assert.That(exceptionData.Keys, Has.Exactly(1).EqualTo("InvalidOperationExceptionData")); + Assert.That(exceptionData["InvalidOperationExceptionData"], Is.TypeOf()); + + var invalidOperationExceptionData = (ExceptionData)exceptionData["InvalidOperationExceptionData"]; + Assert.That(invalidOperationExceptionData, + Has.Exactly(1).EqualTo(new KeyValuePair("InvalidOperationExceptionKey", + "InvalidOperationExceptionValue"))); + Assert.That(invalidOperationExceptionData.Keys, Has.Exactly(1).EqualTo("DivideByZeroExceptionData")); + + var divideByZeroExceptionData = (ExceptionData)invalidOperationExceptionData["DivideByZeroExceptionData"]; + Assert.That(divideByZeroExceptionData, + Has.Exactly(1).EqualTo(new KeyValuePair("DivideByZeroKey", "DivideByZeroValue"))); + } + + [Test] public void Create_ProjectAndException_ProjectIsEqual() { diff --git a/src/tests/SharpRaven.UnitTests/Helper.cs b/src/tests/SharpRaven.UnitTests/Helper.cs index cdb7078f..ee258514 100644 --- a/src/tests/SharpRaven.UnitTests/Helper.cs +++ b/src/tests/SharpRaven.UnitTests/Helper.cs @@ -42,7 +42,9 @@ public static void FirstLevelException() } catch (Exception e) { - throw new Exception("First Level Exception", e); + var exception = new Exception("First Level Exception", e); + exception.Data.Add("FirstLevelExceptionKey", "FirstLevelExceptionValue"); + throw exception; } } @@ -86,7 +88,13 @@ private static void SecondLevelException() } catch (Exception e) { - throw new InvalidOperationException("Second Level Exception", e); + e.Data.Add("DivideByZeroKey", "DivideByZeroValue"); + + var invalidOperationException = new InvalidOperationException("Second Level Exception", e); + + invalidOperationException.Data.Add("InvalidOperationExceptionKey", "InvalidOperationExceptionValue"); + + throw invalidOperationException; } } } From 160efa8ca4a04d346633c8e29ced3884f1687648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 20 Nov 2015 17:13:50 +0100 Subject: [PATCH 125/171] Added back the Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtrasObjectEvenWithTheSameKey test --- .../Data/JsonPacketFactoryTests.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs index 64572712..2e886816 100644 --- a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs +++ b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs @@ -103,6 +103,20 @@ public void Create_Project_ServerNameEqualsMachineName() Assert.That(json.ServerName, Is.EqualTo(Environment.MachineName)); } + [Test] + public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtrasObjectEvenWithTheSameKey() + { + var project = Guid.NewGuid().ToString(); + var exception = new Exception("Error"); + exception.Data.Add("key", "value"); + var json = this.jsonPacketFactory.Create(project, exception, extra: new { ExceptionData = "ExceptionValue" }); + + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("ExceptionData", "ExceptionValue"))); + Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData0")); + Assert.That(json.Extra["ExceptionData0"], Is.TypeOf()); + Assert.That(json.Extra["ExceptionData0"], Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); + } + [Test] public void Create_ProjectAndException_DataPropertyIsSavedInExtras() From 38067a79bd808b5adb92a41a159d85cf85a4a1ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Fri, 20 Nov 2015 17:14:08 +0100 Subject: [PATCH 126/171] R# cleanup --- .../Data/JsonPacketFactoryTests.cs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs index 2e886816..01d6aacb 100644 --- a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs +++ b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs @@ -103,20 +103,6 @@ public void Create_Project_ServerNameEqualsMachineName() Assert.That(json.ServerName, Is.EqualTo(Environment.MachineName)); } - [Test] - public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtrasObjectEvenWithTheSameKey() - { - var project = Guid.NewGuid().ToString(); - var exception = new Exception("Error"); - exception.Data.Add("key", "value"); - var json = this.jsonPacketFactory.Create(project, exception, extra: new { ExceptionData = "ExceptionValue" }); - - Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("ExceptionData", "ExceptionValue"))); - Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData0")); - Assert.That(json.Extra["ExceptionData0"], Is.TypeOf()); - Assert.That(json.Extra["ExceptionData0"], Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); - } - [Test] public void Create_ProjectAndException_DataPropertyIsSavedInExtras() @@ -147,6 +133,20 @@ public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtra } + [Test] + public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtrasObjectEvenWithTheSameKey() + { + var project = Guid.NewGuid().ToString(); + var exception = new Exception("Error"); + exception.Data.Add("key", "value"); + var json = this.jsonPacketFactory.Create(project, exception, extra : new { ExceptionData = "ExceptionValue" }); + + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("ExceptionData", "ExceptionValue"))); + Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData0")); + Assert.That(json.Extra["ExceptionData0"], Is.TypeOf()); + Assert.That(json.Extra["ExceptionData0"], Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); + } + [Test] public void Create_ProjectAndException_EventIDIsValidGuid() From 319c5e15d13d427d7b3b234a7703d3be33fe51cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 25 Nov 2015 16:26:02 +0100 Subject: [PATCH 127/171] Write the serialized JSON to console for easier debugging --- .../Data/JsonPacketFactoryTests.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs index 01d6aacb..d031dcfa 100644 --- a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs +++ b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs @@ -112,6 +112,8 @@ public void Create_ProjectAndException_DataPropertyIsSavedInExtras() exception.Data.Add("key", "value"); var json = this.jsonPacketFactory.Create(project, exception); + Console.WriteLine(JsonConvert.SerializeObject(json, Formatting.Indented)); + Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData")); Assert.That(json.Extra["ExceptionData"], Is.TypeOf()); Assert.That(json.Extra["ExceptionData"], Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); @@ -126,6 +128,8 @@ public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtra exception.Data.Add("key", "value"); var json = this.jsonPacketFactory.Create(project, exception, extra : new { key2 = "value2" }); + Console.WriteLine(JsonConvert.SerializeObject(json, Formatting.Indented)); + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key2", "value2"))); Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData")); Assert.That(json.Extra["ExceptionData"], Is.TypeOf()); @@ -141,6 +145,8 @@ public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtra exception.Data.Add("key", "value"); var json = this.jsonPacketFactory.Create(project, exception, extra : new { ExceptionData = "ExceptionValue" }); + Console.WriteLine(JsonConvert.SerializeObject(json, Formatting.Indented)); + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("ExceptionData", "ExceptionValue"))); Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData0")); Assert.That(json.Extra["ExceptionData0"], Is.TypeOf()); @@ -187,9 +193,7 @@ public void Create_ProjectAndException_NestedExceptionsAndExtraAreStoredInExtras var exception = Helper.GetException(); var json = this.jsonPacketFactory.Create(project, exception, extra : new { ExtraKey = "ExtraValue" }); - var s = JsonConvert.SerializeObject(json, Formatting.Indented); - - Console.WriteLine(s); + Console.WriteLine(JsonConvert.SerializeObject(json, Formatting.Indented)); Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("ExtraKey", "ExtraValue"))); Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData")); From a1f0787c27441e99060e932eda65356f96ee27cb Mon Sep 17 00:00:00 2001 From: Jakub Malczak Date: Tue, 1 Dec 2015 16:24:03 +0900 Subject: [PATCH 128/171] Added failing test testing fo presence of unwanted member --- .../Data/JsonPacketFactoryTests.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs index 01d6aacb..7ceaa504 100644 --- a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs +++ b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs @@ -124,7 +124,7 @@ public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtra var project = Guid.NewGuid().ToString(); var exception = new Exception("Error"); exception.Data.Add("key", "value"); - var json = this.jsonPacketFactory.Create(project, exception, extra : new { key2 = "value2" }); + var json = this.jsonPacketFactory.Create(project, exception, extra: new { key2 = "value2" }); Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key2", "value2"))); Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData")); @@ -133,13 +133,24 @@ public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtra } + [Test] + public void Create_ProjectAndException_ExtraObjectIsSavedWithoutUnnecessaryProperties() + { + var project = Guid.NewGuid().ToString(); + var exception = new Exception("Error"); + var json = this.jsonPacketFactory.Create(project, exception, extra: new Dictionary { { "key", "value2" } }); + + Assert.That(json.Extra.Keys, Has.No.Member("Count")); + } + + [Test] public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtrasObjectEvenWithTheSameKey() { var project = Guid.NewGuid().ToString(); var exception = new Exception("Error"); exception.Data.Add("key", "value"); - var json = this.jsonPacketFactory.Create(project, exception, extra : new { ExceptionData = "ExceptionValue" }); + var json = this.jsonPacketFactory.Create(project, exception, extra: new { ExceptionData = "ExceptionValue" }); Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("ExceptionData", "ExceptionValue"))); Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData0")); @@ -185,7 +196,7 @@ public void Create_ProjectAndException_NestedExceptionsAndExtraAreStoredInExtras { var project = Guid.NewGuid().ToString(); var exception = Helper.GetException(); - var json = this.jsonPacketFactory.Create(project, exception, extra : new { ExtraKey = "ExtraValue" }); + var json = this.jsonPacketFactory.Create(project, exception, extra: new { ExtraKey = "ExtraValue" }); var s = JsonConvert.SerializeObject(json, Formatting.Indented); From bdd899546d91290b7c9b93a6254136781fede0a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 1 Dec 2015 20:19:13 +0100 Subject: [PATCH 129/171] Ensure that IDictionary and IEnumerable> are serialized properly --- src/app/SharpRaven/Data/JsonPacketFactory.cs | 65 +++++++++++++++++-- .../Data/JsonPacketFactoryTests.cs | 55 ++++++++++++---- 2 files changed, 100 insertions(+), 20 deletions(-) diff --git a/src/app/SharpRaven/Data/JsonPacketFactory.cs b/src/app/SharpRaven/Data/JsonPacketFactory.cs index c66a6b26..25881237 100644 --- a/src/app/SharpRaven/Data/JsonPacketFactory.cs +++ b/src/app/SharpRaven/Data/JsonPacketFactory.cs @@ -29,6 +29,7 @@ #endregion using System; +using System.Collections; using System.Collections.Generic; using System.Reflection; @@ -159,17 +160,69 @@ private static IDictionary Convert(object extra, Exception excep if (extra != null) { - foreach (var property in extra.GetType().GetProperties()) + var dictionary = extra as IDictionary; + var enumerable = extra as IEnumerable; + + if (dictionary != null) { - try + foreach (var k in dictionary.Keys) { - var value = property.GetValue(extra, BindingFlags.Default, null, null, null); - var key = UniqueKey(result, property.Name); + var value = dictionary[k]; + var key = UniqueKey(result, k); result.Add(key, value); } - catch (Exception e) + } + else if (enumerable != null) + { + foreach (var e in enumerable) + { + if (e == null) + continue; + + var stringStringKvp = e as KeyValuePair?; + + if (stringStringKvp != null) + { + var key = UniqueKey(result, stringStringKvp.Value.Key); + result.Add(key, stringStringKvp.Value.Value); + continue; + } + + var stringObjectKvp = e as KeyValuePair?; + + if (stringObjectKvp != null) + { + var key = UniqueKey(result, stringObjectKvp.Value.Key); + result.Add(key, stringObjectKvp.Value.Value); + continue; + } + + if (e.GetType().IsGenericType && typeof(KeyValuePair<,>).IsAssignableFrom(e.GetType().GetGenericTypeDefinition())) + { + var keyObject = e.GetType().GetProperty("Key").GetValue(e); + var key = keyObject != null ? keyObject as string ?? keyObject.ToString() : null; + if (key == null) + continue; + + var value = e.GetType().GetProperty("Value").GetValue(e); + result.Add(key, value); + } + } + } + else + { + foreach (var property in extra.GetType().GetProperties()) { - Console.WriteLine("ERROR: " + e); + try + { + var value = property.GetValue(extra, BindingFlags.Default, null, null, null); + var key = UniqueKey(result, property.Name); + result.Add(key, value); + } + catch (Exception e) + { + Console.WriteLine("ERROR: " + e); + } } } } diff --git a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs index 7a361e0e..111c0265 100644 --- a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs +++ b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs @@ -52,6 +52,44 @@ public void SetUp() #endregion + [Test] + public void Create_ExtraIsDictionary_ExtraIsSerializedWithOnlyKeyValues() + { + var project = Guid.NewGuid().ToString(); + var exception = new Exception("Error"); + var extra = new Dictionary { { "key", "value2" } }; + var json = this.jsonPacketFactory.Create(project, exception, extra : extra); + + Console.WriteLine(json); + + Assert.That(json.Extra.Keys, Has.No.Member("Count")); + Assert.That(json.Extra.Keys, Has.No.Member("Keys")); + Assert.That(json.Extra.Keys, Has.No.Member("Values")); + Assert.That(json.Extra.Keys, Has.No.Member("Comparer")); + Assert.That(json.Extra.Keys, Has.Member("ExceptionData")); + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value2"))); + } + + + [Test] + public void Create_ExtraIsEnumerable_ExtraIsSerializedWithOnlyKeyValues() + { + var project = Guid.NewGuid().ToString(); + var exception = new Exception("Error"); + var extra = new[] { new KeyValuePair("key", "value2") }; + var json = this.jsonPacketFactory.Create(project, exception, extra : extra); + + Console.WriteLine(json); + + Assert.That(json.Extra.Keys, Has.No.Member("Count")); + Assert.That(json.Extra.Keys, Has.No.Member("Keys")); + Assert.That(json.Extra.Keys, Has.No.Member("Values")); + Assert.That(json.Extra.Keys, Has.No.Member("Comparer")); + Assert.That(json.Extra.Keys, Has.Member("ExceptionData")); + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value2"))); + } + + [Test] public void Create_InvokesOnCreate() { @@ -126,7 +164,7 @@ public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtra var project = Guid.NewGuid().ToString(); var exception = new Exception("Error"); exception.Data.Add("key", "value"); - var json = this.jsonPacketFactory.Create(project, exception, extra: new { key2 = "value2" }); + var json = this.jsonPacketFactory.Create(project, exception, extra : new { key2 = "value2" }); Console.WriteLine(JsonConvert.SerializeObject(json, Formatting.Indented)); @@ -137,24 +175,13 @@ public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtra } - [Test] - public void Create_ProjectAndException_ExtraObjectIsSavedWithoutUnnecessaryProperties() - { - var project = Guid.NewGuid().ToString(); - var exception = new Exception("Error"); - var json = this.jsonPacketFactory.Create(project, exception, extra: new Dictionary { { "key", "value2" } }); - - Assert.That(json.Extra.Keys, Has.No.Member("Count")); - } - - [Test] public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtrasObjectEvenWithTheSameKey() { var project = Guid.NewGuid().ToString(); var exception = new Exception("Error"); exception.Data.Add("key", "value"); - var json = this.jsonPacketFactory.Create(project, exception, extra: new { ExceptionData = "ExceptionValue" }); + var json = this.jsonPacketFactory.Create(project, exception, extra : new { ExceptionData = "ExceptionValue" }); Console.WriteLine(JsonConvert.SerializeObject(json, Formatting.Indented)); @@ -202,7 +229,7 @@ public void Create_ProjectAndException_NestedExceptionsAndExtraAreStoredInExtras { var project = Guid.NewGuid().ToString(); var exception = Helper.GetException(); - var json = this.jsonPacketFactory.Create(project, exception, extra: new { ExtraKey = "ExtraValue" }); + var json = this.jsonPacketFactory.Create(project, exception, extra : new { ExtraKey = "ExtraValue" }); Console.WriteLine(JsonConvert.SerializeObject(json, Formatting.Indented)); From 4841f0af69f4d651d698776dd4e2f04ca81246b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 2 Dec 2015 07:48:59 +0100 Subject: [PATCH 130/171] Use the PropertyInfo.GetValue(string, object[]) overload to have backward compatibility with .NET 4.0 --- src/app/SharpRaven/Data/JsonPacketFactory.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/SharpRaven/Data/JsonPacketFactory.cs b/src/app/SharpRaven/Data/JsonPacketFactory.cs index 25881237..553fa159 100644 --- a/src/app/SharpRaven/Data/JsonPacketFactory.cs +++ b/src/app/SharpRaven/Data/JsonPacketFactory.cs @@ -199,12 +199,12 @@ private static IDictionary Convert(object extra, Exception excep if (e.GetType().IsGenericType && typeof(KeyValuePair<,>).IsAssignableFrom(e.GetType().GetGenericTypeDefinition())) { - var keyObject = e.GetType().GetProperty("Key").GetValue(e); + var keyObject = e.GetType().GetProperty("Key").GetValue(e, null); var key = keyObject != null ? keyObject as string ?? keyObject.ToString() : null; if (key == null) continue; - var value = e.GetType().GetProperty("Value").GetValue(e); + var value = e.GetType().GetProperty("Value").GetValue(e, null); result.Add(key, value); } } From 2c1fe9858c0a74d8855656eb0fa651777909ec4f Mon Sep 17 00:00:00 2001 From: timor Date: Thu, 10 Dec 2015 20:22:00 +0100 Subject: [PATCH 131/171] Remove the obsolete, not implemented SocialSecurityFilter from the default LogScrubber filters --- src/app/SharpRaven/Logging/LogScrubber.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/SharpRaven/Logging/LogScrubber.cs b/src/app/SharpRaven/Logging/LogScrubber.cs index 3d8c6d3b..2e9aece6 100644 --- a/src/app/SharpRaven/Logging/LogScrubber.cs +++ b/src/app/SharpRaven/Logging/LogScrubber.cs @@ -52,8 +52,7 @@ public LogScrubber() this.filters = new List { new CreditCardFilter(), - new PhoneNumberFilter(), - new SocialSecurityFilter() + new PhoneNumberFilter() }; } From 169675536b15e947a7ae8d93bde626328e5688e7 Mon Sep 17 00:00:00 2001 From: timor Date: Thu, 10 Dec 2015 20:22:51 +0100 Subject: [PATCH 132/171] Add more accurate documentation for the LogScrubber constructor --- src/app/SharpRaven/Logging/LogScrubber.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/SharpRaven/Logging/LogScrubber.cs b/src/app/SharpRaven/Logging/LogScrubber.cs index 2e9aece6..fd1f700c 100644 --- a/src/app/SharpRaven/Logging/LogScrubber.cs +++ b/src/app/SharpRaven/Logging/LogScrubber.cs @@ -45,7 +45,8 @@ public class LogScrubber : IScrubber /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class and adds CreditCardFilter and US-style PhoneNumberFilter + /// to the filter collection used to scrub the JSON packet. /// public LogScrubber() { From 4b1479b1bc43f793b5adca7e0c73f955f10aa9f4 Mon Sep 17 00:00:00 2001 From: timor Date: Fri, 11 Dec 2015 08:29:28 +0100 Subject: [PATCH 133/171] Update tests to reflect less filters in scrubber --- .../SharpRaven.UnitTests/Logging/LogScrubberTests.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/tests/SharpRaven.UnitTests/Logging/LogScrubberTests.cs b/src/tests/SharpRaven.UnitTests/Logging/LogScrubberTests.cs index 688b091f..816efe62 100644 --- a/src/tests/SharpRaven.UnitTests/Logging/LogScrubberTests.cs +++ b/src/tests/SharpRaven.UnitTests/Logging/LogScrubberTests.cs @@ -67,18 +67,10 @@ public void Filters_ContainPhoneNumberFilter() } - [Test] - public void Filters_ContainSocialSecurityFilter() - { - Assert.That(this.scrubber.Filters.OfType().ToArray(), - Has.Length.EqualTo(1)); - } - - [Test] public void Filters_HasExpectedCount() { - Assert.That(this.scrubber.Filters, Has.Count.EqualTo(3)); + Assert.That(this.scrubber.Filters, Has.Count.EqualTo(2)); } From fdfcb89f7708b5136a10e87e21f5806414633a7a Mon Sep 17 00:00:00 2001 From: timor Date: Fri, 11 Dec 2015 08:55:30 +0100 Subject: [PATCH 134/171] Remove the @ in LogScrubberTests class name --- src/tests/SharpRaven.UnitTests/Logging/LogScrubberTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/SharpRaven.UnitTests/Logging/LogScrubberTests.cs b/src/tests/SharpRaven.UnitTests/Logging/LogScrubberTests.cs index 816efe62..9fce22d4 100644 --- a/src/tests/SharpRaven.UnitTests/Logging/LogScrubberTests.cs +++ b/src/tests/SharpRaven.UnitTests/Logging/LogScrubberTests.cs @@ -39,7 +39,7 @@ namespace SharpRaven.UnitTests.Logging { [TestFixture] - public class @LogScrubberTests + public class LogScrubberTests { #region SetUp/Teardown From 28376d44680dec9d4b5dea9e4eded703782e43c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 2 Dec 2015 10:35:59 +0100 Subject: [PATCH 135/171] Use JContainer.Merge() and some custom array logic to merge exception.Data and extra objects. --- src/app/SharpRaven/Data/ExceptionData.cs | 43 ++++-- src/app/SharpRaven/Data/IJsonPacketFactory.cs | 12 +- src/app/SharpRaven/Data/JsonPacket.cs | 2 +- src/app/SharpRaven/Data/JsonPacketFactory.cs | 122 +++++------------- .../Data/JsonPacketFactoryTests.cs | 113 +++++++++------- .../SharpRaven.UnitTests.csproj | 1 + 6 files changed, 139 insertions(+), 154 deletions(-) diff --git a/src/app/SharpRaven/Data/ExceptionData.cs b/src/app/SharpRaven/Data/ExceptionData.cs index d93c9931..309ee18e 100644 --- a/src/app/SharpRaven/Data/ExceptionData.cs +++ b/src/app/SharpRaven/Data/ExceptionData.cs @@ -31,6 +31,8 @@ using System; using System.Collections.Generic; +using Newtonsoft.Json; + namespace SharpRaven.Data { /// @@ -38,7 +40,7 @@ namespace SharpRaven.Data /// public class ExceptionData : Dictionary { - private readonly Exception exception; + private readonly string exceptionType; /// Initializes a new instance of the class. @@ -48,14 +50,14 @@ public ExceptionData(Exception exception) if (exception == null) throw new ArgumentNullException("exception"); - this.exception = exception; + this.exceptionType = exception.GetType().FullName; foreach (var k in exception.Data.Keys) { try { var value = exception.Data[k]; - var key = JsonPacketFactory.UniqueKey(this, k); + var key = k as string ?? k.ToString(); Add(key, value); } catch (Exception e) @@ -72,13 +74,38 @@ public ExceptionData(Exception exception) } - /// Adds the current instance to the specified . - /// The dictionary to current instance to. - public void AddTo(IDictionary dictionary) + /// Gets the type of the exception. + /// The type of the exception. + [JsonProperty("type")] + public string ExceptionType { - var key = String.Concat(this.exception.GetType().Name, "Data"); - key = JsonPacketFactory.UniqueKey(dictionary, key); + get { return this.exceptionType; } + } + + + private void AddTo(IDictionary dictionary) + { + var key = String.Concat(ExceptionType, '.', "Data"); + key = UniqueKey(dictionary, key); dictionary.Add(key, this); } + + + private static string UniqueKey(IDictionary dictionary, object key) + { + var stringKey = key as string ?? key.ToString(); + + if (!dictionary.ContainsKey(stringKey)) + return stringKey; + + for (var i = 0; i < 10000; i++) + { + var newKey = String.Concat(stringKey, i); + if (!dictionary.ContainsKey(newKey)) + return newKey; + } + + throw new ArgumentException(String.Format("Unable to find a unique key for '{0}'.", stringKey), "key"); + } } } \ No newline at end of file diff --git a/src/app/SharpRaven/Data/IJsonPacketFactory.cs b/src/app/SharpRaven/Data/IJsonPacketFactory.cs index b8a1676a..a3139101 100644 --- a/src/app/SharpRaven/Data/IJsonPacketFactory.cs +++ b/src/app/SharpRaven/Data/IJsonPacketFactory.cs @@ -2,21 +2,21 @@ // Copyright (c) 2014 The Sentry Team and individual contributors. // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are permitted // provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // 3. Neither the name of the Sentry nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR @@ -94,4 +94,4 @@ JsonPacket Create(string project, string[] fingerprint = null, object extra = null); } -} +} \ No newline at end of file diff --git a/src/app/SharpRaven/Data/JsonPacket.cs b/src/app/SharpRaven/Data/JsonPacket.cs index 29ce1fe0..74f4a4b6 100644 --- a/src/app/SharpRaven/Data/JsonPacket.cs +++ b/src/app/SharpRaven/Data/JsonPacket.cs @@ -171,7 +171,7 @@ private JsonPacket() /// An arbitrary mapping of additional metadata to store with the event. /// [JsonProperty(PropertyName = "extra", NullValueHandling = NullValueHandling.Ignore)] - public IDictionary Extra { get; set; } + public object Extra { get; set; } /// /// The record severity. diff --git a/src/app/SharpRaven/Data/JsonPacketFactory.cs b/src/app/SharpRaven/Data/JsonPacketFactory.cs index 553fa159..9ee7de79 100644 --- a/src/app/SharpRaven/Data/JsonPacketFactory.cs +++ b/src/app/SharpRaven/Data/JsonPacketFactory.cs @@ -29,9 +29,10 @@ #endregion using System; -using System.Collections; using System.Collections.Generic; -using System.Reflection; +using System.Linq; + +using Newtonsoft.Json.Linq; namespace SharpRaven.Data { @@ -69,7 +70,7 @@ public JsonPacket Create(string project, Level = level, Tags = tags, Fingerprint = fingerprint, - Extra = Convert(extra) + Extra = Merge(extra) }; return OnCreate(json); @@ -112,7 +113,7 @@ public JsonPacket Create(string project, Level = level, Tags = tags, Fingerprint = fingerprint, - Extra = Convert(extra, exception) + Extra = Merge(extra, exception) }; return OnCreate(json); @@ -133,105 +134,48 @@ protected virtual JsonPacket OnCreate(JsonPacket jsonPacket) } - internal static string UniqueKey(IDictionary dictionary, object key) + private static object Merge(object extra, Exception exception = null) { - var stringKey = key as string ?? key.ToString(); - - if (!dictionary.ContainsKey(stringKey)) - return stringKey; - - for (var i = 0; i < 10000; i++) - { - var newKey = String.Concat(stringKey, i); - if (!dictionary.ContainsKey(newKey)) - return newKey; - } + if (exception == null && extra == null) + return null; - throw new ArgumentException(String.Format("Unable to find a unique key for '{0}'.", stringKey), "key"); - } + if (extra != null && exception == null) + return extra; + var exceptionData = new ExceptionData(exception); - private static IDictionary Convert(object extra, Exception exception = null) - { - if (exception == null && extra == null) - return null; + if (extra == null) + return exceptionData; - var result = new Dictionary(); + JObject result; - if (extra != null) + if (extra.GetType().IsArray) { - var dictionary = extra as IDictionary; - var enumerable = extra as IEnumerable; + result = new JObject(); + var array = JArray.FromObject(extra); - if (dictionary != null) + foreach (var o in array) { - foreach (var k in dictionary.Keys) - { - var value = dictionary[k]; - var key = UniqueKey(result, k); - result.Add(key, value); - } - } - else if (enumerable != null) - { - foreach (var e in enumerable) - { - if (e == null) - continue; - - var stringStringKvp = e as KeyValuePair?; - - if (stringStringKvp != null) - { - var key = UniqueKey(result, stringStringKvp.Value.Key); - result.Add(key, stringStringKvp.Value.Value); - continue; - } - - var stringObjectKvp = e as KeyValuePair?; - - if (stringObjectKvp != null) - { - var key = UniqueKey(result, stringObjectKvp.Value.Key); - result.Add(key, stringObjectKvp.Value.Value); - continue; - } - - if (e.GetType().IsGenericType && typeof(KeyValuePair<,>).IsAssignableFrom(e.GetType().GetGenericTypeDefinition())) - { - var keyObject = e.GetType().GetProperty("Key").GetValue(e, null); - var key = keyObject != null ? keyObject as string ?? keyObject.ToString() : null; - if (key == null) - continue; - - var value = e.GetType().GetProperty("Value").GetValue(e, null); - result.Add(key, value); - } - } - } - else - { - foreach (var property in extra.GetType().GetProperties()) + var jo = o as JObject; + JProperty[] properties; + + if (jo == null || (properties = jo.Properties().ToArray()).Length != 2 || properties[0].Name != "Key" + || properties[1].Name != "Value") { - try - { - var value = property.GetValue(extra, BindingFlags.Default, null, null, null); - var key = UniqueKey(result, property.Name); - result.Add(key, value); - } - catch (Exception e) - { - Console.WriteLine("ERROR: " + e); - } + result.Merge(o); + continue; } + + var key = properties[0].Value.ToString(); + var value = properties[1].Value; + result.Add(key, value); } } + else + result = JObject.FromObject(extra); - if (exception == null) - return result; - - var exceptionData = new ExceptionData(exception); - exceptionData.AddTo(result); + var jExceptionData = JObject.FromObject(exceptionData); + result.Merge(jExceptionData); return result; } diff --git a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs index 111c0265..efd5ecde 100644 --- a/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs +++ b/src/tests/SharpRaven.UnitTests/Data/JsonPacketFactoryTests.cs @@ -32,6 +32,7 @@ using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using NUnit.Framework; @@ -60,14 +61,14 @@ public void Create_ExtraIsDictionary_ExtraIsSerializedWithOnlyKeyValues() var extra = new Dictionary { { "key", "value2" } }; var json = this.jsonPacketFactory.Create(project, exception, extra : extra); - Console.WriteLine(json); + var jsonString = JsonConvert.SerializeObject(json, Formatting.Indented); + Console.WriteLine(jsonString); - Assert.That(json.Extra.Keys, Has.No.Member("Count")); - Assert.That(json.Extra.Keys, Has.No.Member("Keys")); - Assert.That(json.Extra.Keys, Has.No.Member("Values")); - Assert.That(json.Extra.Keys, Has.No.Member("Comparer")); - Assert.That(json.Extra.Keys, Has.Member("ExceptionData")); - Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value2"))); + Assert.That(jsonString, Is.Not.StringContaining("Count")); + Assert.That(jsonString, Is.Not.StringContaining("Keys")); + Assert.That(jsonString, Is.Not.StringContaining("Values")); + Assert.That(jsonString, Is.Not.StringContaining("Comparer")); + Assert.That(jsonString, Is.StringContaining(@"""key"": ""value2""")); } @@ -76,17 +77,23 @@ public void Create_ExtraIsEnumerable_ExtraIsSerializedWithOnlyKeyValues() { var project = Guid.NewGuid().ToString(); var exception = new Exception("Error"); - var extra = new[] { new KeyValuePair("key", "value2") }; + var extra = new[] { new KeyValuePair("key1", "value1"), new KeyValuePair("key2", "value2") }; var json = this.jsonPacketFactory.Create(project, exception, extra : extra); - Console.WriteLine(json); + var jsonString = JsonConvert.SerializeObject(json.Extra, Formatting.Indented); + Console.WriteLine(jsonString); - Assert.That(json.Extra.Keys, Has.No.Member("Count")); - Assert.That(json.Extra.Keys, Has.No.Member("Keys")); - Assert.That(json.Extra.Keys, Has.No.Member("Values")); - Assert.That(json.Extra.Keys, Has.No.Member("Comparer")); - Assert.That(json.Extra.Keys, Has.Member("ExceptionData")); - Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value2"))); + Assert.That(jsonString, Is.Not.StringContaining("Count")); + Assert.That(jsonString, Is.Not.StringContaining("Keys")); + Assert.That(jsonString, Is.Not.StringContaining("Values")); + Assert.That(jsonString, Is.Not.StringContaining("Comparer")); + Assert.That(json.Extra, Is.TypeOf()); + + var jExtra = (JObject)json.Extra; + Assert.That(jExtra.Property("key1"), Is.Not.Null, "key1"); + Assert.That(jExtra.Property("key1").Value.ToString(), Is.EqualTo("value1")); + Assert.That(jExtra.Property("key2"), Is.Not.Null, "key2"); + Assert.That(jExtra.Property("key2").Value.ToString(), Is.EqualTo("value2")); } @@ -150,11 +157,9 @@ public void Create_ProjectAndException_DataPropertyIsSavedInExtras() exception.Data.Add("key", "value"); var json = this.jsonPacketFactory.Create(project, exception); - Console.WriteLine(JsonConvert.SerializeObject(json, Formatting.Indented)); + Console.WriteLine(JsonConvert.SerializeObject(json.Extra, Formatting.Indented)); - Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData")); - Assert.That(json.Extra["ExceptionData"], Is.TypeOf()); - Assert.That(json.Extra["ExceptionData"], Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); + Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); } @@ -166,12 +171,15 @@ public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtra exception.Data.Add("key", "value"); var json = this.jsonPacketFactory.Create(project, exception, extra : new { key2 = "value2" }); - Console.WriteLine(JsonConvert.SerializeObject(json, Formatting.Indented)); + Console.WriteLine(JsonConvert.SerializeObject(json.Extra, Formatting.Indented)); + + Assert.That(json.Extra, Is.TypeOf()); + var extra = (JObject)json.Extra; - Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("key2", "value2"))); - Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData")); - Assert.That(json.Extra["ExceptionData"], Is.TypeOf()); - Assert.That(json.Extra["ExceptionData"], Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); + Assert.That(extra.Property("key"), Is.Not.Null, "key"); + Assert.That(extra.Property("key").Value.ToString(), Is.EqualTo("value")); + Assert.That(extra.Property("key2"), Is.Not.Null, "key2"); + Assert.That(extra.Property("key2").Value.ToString(), Is.EqualTo("value2")); } @@ -183,12 +191,15 @@ public void Create_ProjectAndException_DataPropertyIsSavedInExtrasAlongWithExtra exception.Data.Add("key", "value"); var json = this.jsonPacketFactory.Create(project, exception, extra : new { ExceptionData = "ExceptionValue" }); - Console.WriteLine(JsonConvert.SerializeObject(json, Formatting.Indented)); + Console.WriteLine(JsonConvert.SerializeObject(json.Extra, Formatting.Indented)); - Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("ExceptionData", "ExceptionValue"))); - Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData0")); - Assert.That(json.Extra["ExceptionData0"], Is.TypeOf()); - Assert.That(json.Extra["ExceptionData0"], Has.Exactly(1).EqualTo(new KeyValuePair("key", "value"))); + Assert.That(json.Extra, Is.TypeOf()); + var extra = (JObject)json.Extra; + + Assert.That(extra.Property("key"), Is.Not.Null, "key"); + Assert.That(extra.Property("key").Value.ToString(), Is.EqualTo("value")); + Assert.That(extra.Property("ExceptionData"), Is.Not.Null, "ExceptionData"); + Assert.That(extra.Property("ExceptionData").Value.ToString(), Is.EqualTo("ExceptionValue")); } @@ -231,27 +242,29 @@ public void Create_ProjectAndException_NestedExceptionsAndExtraAreStoredInExtras var exception = Helper.GetException(); var json = this.jsonPacketFactory.Create(project, exception, extra : new { ExtraKey = "ExtraValue" }); - Console.WriteLine(JsonConvert.SerializeObject(json, Formatting.Indented)); - - Assert.That(json.Extra, Has.Exactly(1).EqualTo(new KeyValuePair("ExtraKey", "ExtraValue"))); - Assert.That(json.Extra.Keys, Has.Exactly(1).EqualTo("ExceptionData")); - Assert.That(json.Extra["ExceptionData"], Is.TypeOf()); - - var exceptionData = (ExceptionData)json.Extra["ExceptionData"]; - Assert.That(exceptionData, - Has.Exactly(1).EqualTo(new KeyValuePair("FirstLevelExceptionKey", "FirstLevelExceptionValue"))); - Assert.That(exceptionData.Keys, Has.Exactly(1).EqualTo("InvalidOperationExceptionData")); - Assert.That(exceptionData["InvalidOperationExceptionData"], Is.TypeOf()); - - var invalidOperationExceptionData = (ExceptionData)exceptionData["InvalidOperationExceptionData"]; - Assert.That(invalidOperationExceptionData, - Has.Exactly(1).EqualTo(new KeyValuePair("InvalidOperationExceptionKey", - "InvalidOperationExceptionValue"))); - Assert.That(invalidOperationExceptionData.Keys, Has.Exactly(1).EqualTo("DivideByZeroExceptionData")); - - var divideByZeroExceptionData = (ExceptionData)invalidOperationExceptionData["DivideByZeroExceptionData"]; - Assert.That(divideByZeroExceptionData, - Has.Exactly(1).EqualTo(new KeyValuePair("DivideByZeroKey", "DivideByZeroValue"))); + Console.WriteLine(JsonConvert.SerializeObject(json.Extra, Formatting.Indented)); + + Assert.That(json.Extra, Is.TypeOf()); + var extra = (JObject)json.Extra; + + Assert.That(extra.Property("ExtraKey"), Is.Not.Null, "ExtraKey"); + Assert.That(extra.Property("ExtraKey").Value.ToString(), Is.EqualTo("ExtraValue")); + Assert.That(extra.Property("FirstLevelExceptionKey"), Is.Not.Null, "FirstLevelExceptionKey"); + Assert.That(extra.Property("FirstLevelExceptionKey").Value.ToString(), Is.EqualTo("FirstLevelExceptionValue")); + Assert.That(extra.Property("System.InvalidOperationException.Data"), Is.Not.Null, "System.InvalidOperationException.Data"); + Assert.That(extra.Property("System.InvalidOperationException.Data").Value, Is.TypeOf()); + + var invalidOperationExceptionData = (JObject)extra.Property("System.InvalidOperationException.Data").Value; + Assert.That(invalidOperationExceptionData.Property("InvalidOperationExceptionKey"), Is.Not.Null, "InvalidOperationExceptionKey"); + Assert.That(invalidOperationExceptionData.Property("InvalidOperationExceptionKey").Value.ToString(), + Is.EqualTo("InvalidOperationExceptionValue")); + Assert.That(invalidOperationExceptionData.Property("System.DivideByZeroException.Data"), Is.Not.Null, + "System.DivideByZeroException.Data"); + Assert.That(invalidOperationExceptionData.Property("System.DivideByZeroException.Data").Value, Is.TypeOf()); + + var divideByZeroExceptionData = (JObject)invalidOperationExceptionData.Property("System.DivideByZeroException.Data").Value; + Assert.That(divideByZeroExceptionData.Property("DivideByZeroKey"), Is.Not.Null, "DivideByZeroKey"); + Assert.That(divideByZeroExceptionData.Property("DivideByZeroKey").Value.ToString(), Is.EqualTo("DivideByZeroValue")); } diff --git a/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj b/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj index 371555b0..e6c07543 100644 --- a/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj +++ b/src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj @@ -57,6 +57,7 @@ false + False ..\..\packages\Newtonsoft.Json.6.0.8\lib\net40\Newtonsoft.Json.dll From 7ffd9d5f4bbf8cc3050291ca802666149472d34d Mon Sep 17 00:00:00 2001 From: David Cramer Date: Tue, 5 Jan 2016 17:33:01 -0800 Subject: [PATCH 136/171] Various Client Additions - Add Environment - Add Travis CI support - Add default Tags - Ensure Release is set on packets --- .travis.yml | 8 ++ Makefile | 12 +- src/app/SharpRaven/Data/JsonPacket.cs | 24 ++-- src/app/SharpRaven/IRavenClient.cs | 27 +++- src/app/SharpRaven/RavenClient.cs | 76 ++++++++--- src/app/SharpRaven/packages.config | 2 +- .../SharpRaven.Nancy.UnitTests/NancyTests.cs | 14 +-- .../SharpRaven.UnitTests/RavenClientTests.cs | 119 ++++++++++++++++-- .../SharpRaven.UnitTests/packages.config | 2 +- src/tests/SharpRaven.WebTest/packages.config | 2 +- 10 files changed, 234 insertions(+), 52 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..d4eeec35 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +language: csharp +solution: src/SharpRaven.sln +sudo: false +install: + - nuget restore src +script: + - xbuild ./src/SharpRaven.build + - mono ./src/packages/NUnit.Runners.2.6.3/tools/nunit-console.exe ./src/tests/SharpRaven.UnitTests/bin/Release/net45/SharpRaven.UnitTests.dll -exclude=NuGet,NoMono -nodots diff --git a/Makefile b/Makefile index 52d44acf..e4b7c36b 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,12 @@ -test: +build: setup-nuget restore + +setup-nuget: + mkdir -p .nuget + wget -O .nuget/nuget.exe https://dist.nuget.org/win-x86-commandline/latest/nuget.exe + +restore: mono --runtime=v4.0.30319 ".nuget/NuGet.exe" Restore "src" + +test: restore xbuild "./src/SharpRaven.build" - mono --runtime=v4.0.30319 ./src/packages/NUnit.Runners.2.6.3/tools/nunit-console.exe ./src/tests/SharpRaven.UnitTests/bin/Release/net45/SharpRaven.UnitTests.dll -exclude=NuGet,NoMono -nodots \ No newline at end of file + mono --runtime=v4.0.30319 ./src/packages/NUnit.Runners.2.6.3/tools/nunit-console.exe ./src/tests/SharpRaven.UnitTests/bin/Release/net45/SharpRaven.UnitTests.dll -exclude=NuGet,NoMono -nodots diff --git a/src/app/SharpRaven/Data/JsonPacket.cs b/src/app/SharpRaven/Data/JsonPacket.cs index 74f4a4b6..681999da 100644 --- a/src/app/SharpRaven/Data/JsonPacket.cs +++ b/src/app/SharpRaven/Data/JsonPacket.cs @@ -2,21 +2,21 @@ // Copyright (c) 2014 The Sentry Team and individual contributors. // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are permitted // provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // 3. Neither the name of the Sentry nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR @@ -121,7 +121,7 @@ private JsonPacket() Modules = SystemUtil.GetModules(); // The current hostname - ServerName = Environment.MachineName; + ServerName = System.Environment.MachineName; // Create timestamp TimeStamp = DateTime.UtcNow; @@ -141,7 +141,11 @@ private JsonPacket() // Platform Platform = "csharp"; + // Release Release = ""; + + // Environment + Environment = ""; } @@ -252,6 +256,12 @@ private JsonPacket() [JsonProperty(PropertyName = "fingerprint", NullValueHandling = NullValueHandling.Ignore)] public string[] Fingerprint { get; set; } + /// + /// Identifies the operating environment (e.g. production). + /// + [JsonProperty(PropertyName = "environment", NullValueHandling = NullValueHandling.Ignore)] + public string Environment { get; set; } + /// /// A map or list of tags for this event. /// @@ -299,4 +309,4 @@ public override string ToString() return JsonConvert.SerializeObject(this); } } -} \ No newline at end of file +} diff --git a/src/app/SharpRaven/IRavenClient.cs b/src/app/SharpRaven/IRavenClient.cs index 6028c58e..33e410c3 100644 --- a/src/app/SharpRaven/IRavenClient.cs +++ b/src/app/SharpRaven/IRavenClient.cs @@ -2,21 +2,21 @@ // Copyright (c) 2014 The Sentry Team and individual contributors. // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are permitted // provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // 3. Neither the name of the Sentry nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR @@ -63,6 +63,21 @@ public interface IRavenClient /// IScrubber LogScrubber { get; set; } + /// + /// Release. + /// + string Release { get; set; } + + /// + /// The environment (e.g. production) + /// + string Environment { get; set; } + + /// + /// Default tags + /// + IDictionary Tags { get; set; } + /// /// Gets or sets the timeout value in milliseconds for the /// and methods. @@ -174,4 +189,4 @@ Task CaptureMessageAsync(SentryMessage message, #endregion } -} \ No newline at end of file +} diff --git a/src/app/SharpRaven/RavenClient.cs b/src/app/SharpRaven/RavenClient.cs index fd572728..b49f5ec0 100644 --- a/src/app/SharpRaven/RavenClient.cs +++ b/src/app/SharpRaven/RavenClient.cs @@ -2,21 +2,21 @@ // Copyright (c) 2014 The Sentry Team and individual contributors. // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are permitted // provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // 3. Neither the name of the Sentry nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR @@ -63,7 +63,6 @@ public RavenClient(IJsonPacketFactory jsonPacketFactory = null) { } - /// /// Initializes a new instance of the class. /// @@ -103,6 +102,7 @@ public RavenClient(Dsn dsn, Logger = "root"; Timeout = TimeSpan.FromSeconds(5); + Tags = new Dictionary(); } @@ -141,6 +141,21 @@ public Dsn CurrentDsn /// public string Logger { get; set; } + /// + /// The version of the application. + /// + public string Release { get; set; } + + /// + /// The environment (e.g. production) + /// + public string Environment { get; set; } + + /// + /// Default tags + /// + public IDictionary Tags { get; set; } + /// /// Gets or sets the timeout value in milliseconds for the HTTP communication with Sentry. /// @@ -194,18 +209,17 @@ public string CaptureException(Exception exception, string[] fingerprint = null, object extra = null) { + var finalTags = MergeDicts(Tags, tags); JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, exception, message, level, - tags, + finalTags, fingerprint, extra); - - return Send(packet, CurrentDsn); + return Send(packet); } - /// /// Captures the message. /// @@ -223,9 +237,14 @@ public string CaptureMessage(SentryMessage message, string[] fingerprint = null, object extra = null) { - JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, message, level, tags, fingerprint, extra); - - return Send(packet, CurrentDsn); + var finalTags = MergeDicts(Tags, tags); + JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, + message, + level, + finalTags, + fingerprint, + extra); + return Send(packet); } @@ -239,6 +258,8 @@ protected virtual JsonPacket PreparePacket(JsonPacket packet) packet.Logger = Logger; packet.User = packet.User ?? this.sentryUserFactory.Create(); packet.Request = packet.Request ?? this.sentryRequestFactory.Create(); + packet.Release = Release; + packet.Environment = Environment; return packet; } @@ -251,18 +272,20 @@ protected virtual JsonPacket PreparePacket(JsonPacket packet) /// /// The of the successfully captured JSON packet, or null if it fails. /// - protected virtual string Send(JsonPacket packet, Dsn dsn) + protected virtual string Send(JsonPacket packet) { try { + // TODO(dcramer): moving this out of Send makes it easier to test the final + // generated packet packet = PreparePacket(packet); - var request = (HttpWebRequest)WebRequest.Create(dsn.SentryUri); + var request = (HttpWebRequest)WebRequest.Create(currentDsn.SentryUri); request.Timeout = (int)Timeout.TotalMilliseconds; request.ReadWriteTimeout = (int)Timeout.TotalMilliseconds; request.Method = "POST"; request.Accept = "application/json"; - request.Headers.Add("X-Sentry-Auth", PacketBuilder.CreateAuthenticationHeader(dsn)); + request.Headers.Add("X-Sentry-Auth", PacketBuilder.CreateAuthenticationHeader(currentDsn)); request.UserAgent = PacketBuilder.UserAgent; if (Compression) @@ -318,6 +341,25 @@ protected virtual string Send(JsonPacket packet, Dsn dsn) } } + private IDictionary MergeDicts(IDictionary one = null, IDictionary two = null) + { + var result = new Dictionary(); + if (one != null) { + foreach (KeyValuePair pair in one) { + result.Add(pair.Key, pair.Value); + } + } + if (two != null) { + foreach (KeyValuePair pair in two) { + if (result.ContainsKey(pair.Key)) { + result[pair.Key] = pair.Value; + } else { + result.Add(pair.Key, pair.Value); + } + } + } + return result; + } private string HandleException(Exception exception) { @@ -360,4 +402,4 @@ private string HandleException(Exception exception) return null; } } -} \ No newline at end of file +} diff --git a/src/app/SharpRaven/packages.config b/src/app/SharpRaven/packages.config index cf052271..2ad8d41a 100644 --- a/src/app/SharpRaven/packages.config +++ b/src/app/SharpRaven/packages.config @@ -2,4 +2,4 @@ - \ No newline at end of file + diff --git a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs index 73248455..cc4b9342 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs @@ -2,21 +2,21 @@ // Copyright (c) 2014 The Sentry Team and individual contributors. // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are permitted // provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // 3. Neither the name of the Sentry nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR @@ -133,7 +133,7 @@ public TestableRavenClient(IJsonPacketFactory jsonPacketFactory) } - protected override string Send(JsonPacket packet, Dsn dsn) + protected override string Send(JsonPacket packet) { // Retrieving the GUID from the JsonPacket verifies that // NancyContextJsonPacketFactory.OnCreate() has been invoked, @@ -144,4 +144,4 @@ protected override string Send(JsonPacket packet, Dsn dsn) } } } -} \ No newline at end of file +} diff --git a/src/tests/SharpRaven.UnitTests/RavenClientTests.cs b/src/tests/SharpRaven.UnitTests/RavenClientTests.cs index 04c5643c..6a81c745 100644 --- a/src/tests/SharpRaven.UnitTests/RavenClientTests.cs +++ b/src/tests/SharpRaven.UnitTests/RavenClientTests.cs @@ -2,21 +2,21 @@ // Copyright (c) 2014 The Sentry Team and individual contributors. // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are permitted // provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // 3. Neither the name of the Sentry nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR @@ -29,6 +29,7 @@ #endregion using System; +using System.Collections.Generic; using NSubstitute; @@ -47,11 +48,12 @@ namespace SharpRaven.UnitTests [TestFixture] public class RavenClientTests { + const string dsnUri = + "http://7d6466e66155431495bdb4036ba9a04b:4c1cfeab7ebd4c1cb9e18008173a3630@app.getsentry.com/3739"; + [Test] public void CaptureMessage_InvokesSend_AndJsonPacketFactoryOnCreate() { - const string dsnUri = - "http://7d6466e66155431495bdb4036ba9a04b:4c1cfeab7ebd4c1cb9e18008173a3630@app.getsentry.com/3739"; var project = Guid.NewGuid().ToString(); var jsonPacketFactory = new TestableJsonPacketFactory(project); var client = new TestableRavenClient(dsnUri, jsonPacketFactory); @@ -131,10 +133,101 @@ public void Logger_IsRoot() } + [Test] + public void Release_IsNullByDefault() + { + IRavenClient ravenClient = new RavenClient(TestHelper.DsnUri); + Assert.That(ravenClient.Release, Is.EqualTo(null)); + } + + [Test] + public void CaptureMessage_SendsLogger() + { + var client = new TestableRavenClient(dsnUri); + client.Logger = "foobar"; + client.CaptureMessage("Test"); + + var lastEvent = client.LastEvent(); + + Assert.That(lastEvent.Logger, Is.EqualTo("foobar")); + } + + [Test] + public void CaptureMessage_SendsRelease() + { + var client = new TestableRavenClient(dsnUri); + client.Release = "foobar"; + client.CaptureMessage("Test"); + + var lastEvent = client.LastEvent(); + + Assert.That(lastEvent.Release, Is.EqualTo("foobar")); + } + + [Test] + public void CaptureMessage_SendsEnvironment() + { + var client = new TestableRavenClient(dsnUri); + client.Environment = "foobar"; + client.CaptureMessage("Test"); + + var lastEvent = client.LastEvent(); + + Assert.That(lastEvent.Environment, Is.EqualTo("foobar")); + } + + [Test] + public void CaptureMessage_TagHandling() + { + var messageTags = new Dictionary(); + messageTags.Add("key", "another value"); + + var client = new TestableRavenClient(dsnUri); + client.Tags.Add("key", "value"); + client.Tags.Add("foo", "bar"); + client.CaptureMessage("Test", ErrorLevel.Info, messageTags); + + var lastEvent = client.LastEvent(); + + Assert.That(lastEvent.Tags["key"], Is.EqualTo("another value")); + Assert.That(lastEvent.Tags["foo"], Is.EqualTo("bar")); + } + + [Test] + public void CaptureMessage_OnlyDefaultTags() + { + var client = new TestableRavenClient(dsnUri); + client.Tags.Add("key", "value"); + client.Tags.Add("foo", "bar"); + client.Tags = defaultTags; + client.CaptureMessage("Test", ErrorLevel.Info); + + var lastEvent = client.LastEvent(); + + Assert.That(lastEvent.Tags["key"], Is.EqualTo("value")); + Assert.That(lastEvent.Tags["foo"], Is.EqualTo("bar")); + } + + [Test] + public void CaptureMessage_OnlyMessageTags() + { + var messageTags = new Dictionary(); + messageTags.Add("key", "value"); + messageTags.Add("foo", "bar"); + + var client = new TestableRavenClient(dsnUri); + client.CaptureMessage("Test", ErrorLevel.Info, messageTags); + + var lastEvent = client.LastEvent(); + + Assert.That(lastEvent.Tags["key"], Is.EqualTo("value")); + Assert.That(lastEvent.Tags["foo"], Is.EqualTo("bar")); + } + private class TestableJsonPacketFactory : JsonPacketFactory { private readonly string project; - + private JsonPacket m_lastEvent; public TestableJsonPacketFactory(string project) { @@ -156,9 +249,15 @@ public TestableRavenClient(string dsn, IJsonPacketFactory jsonPacketFactory = nu { } + public JsonPacket LastEvent() { + return m_lastEvent; + } - protected override string Send(JsonPacket packet, Dsn dsn) + protected override string Send(JsonPacket packet) { + // TODO(dcramer): this is duped from RavenClient + packet = PreparePacket(packet); + m_lastEvent = packet; return packet.Project; } @@ -171,4 +270,4 @@ protected override Task SendAsync(JsonPacket packet, Dsn dsn) #endif } } -} \ No newline at end of file +} diff --git a/src/tests/SharpRaven.UnitTests/packages.config b/src/tests/SharpRaven.UnitTests/packages.config index ac43f023..7454ad84 100644 --- a/src/tests/SharpRaven.UnitTests/packages.config +++ b/src/tests/SharpRaven.UnitTests/packages.config @@ -4,4 +4,4 @@ - \ No newline at end of file + diff --git a/src/tests/SharpRaven.WebTest/packages.config b/src/tests/SharpRaven.WebTest/packages.config index df8813bb..b02751e9 100644 --- a/src/tests/SharpRaven.WebTest/packages.config +++ b/src/tests/SharpRaven.WebTest/packages.config @@ -1,4 +1,4 @@  - \ No newline at end of file + From 6267b7eb01f3333aacde9486d5b62ac0dbbd74bb Mon Sep 17 00:00:00 2001 From: Erik Hvattum Date: Tue, 12 Jan 2016 16:23:35 +0100 Subject: [PATCH 137/171] Added a nullcheck on the NancyConfiguration.Settings, since we allow null a little later. We dont want the logging to crash anything. --- .../SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs index 0d556d6a..73f7acd9 100644 --- a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs +++ b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs @@ -51,7 +51,10 @@ public class NancyContextJsonPacketFactory : JsonPacketFactory /// protected override JsonPacket OnCreate(JsonPacket jsonPacket) { - var nancyContextDataSlot = NancyConfiguration.Settings.NancyContextDataSlot; + var nancyContextDataSlot = NancyConfiguration.Settings?.NancyContextDataSlot; + if (nancyContextDataSlot == null) + return jsonPacket; + var nancyContext = CallContext.LogicalGetData(nancyContextDataSlot) as NancyContext; if (nancyContext == null) From da4f372495a4d7b3695af2873c0c74f2a7e0cd61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 13 Jan 2016 08:46:29 +0100 Subject: [PATCH 138/171] Make stuff compile --- src/tests/SharpRaven.UnitTests/RavenClientTests.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/tests/SharpRaven.UnitTests/RavenClientTests.cs b/src/tests/SharpRaven.UnitTests/RavenClientTests.cs index 6a81c745..184c44c2 100644 --- a/src/tests/SharpRaven.UnitTests/RavenClientTests.cs +++ b/src/tests/SharpRaven.UnitTests/RavenClientTests.cs @@ -199,7 +199,7 @@ public void CaptureMessage_OnlyDefaultTags() var client = new TestableRavenClient(dsnUri); client.Tags.Add("key", "value"); client.Tags.Add("foo", "bar"); - client.Tags = defaultTags; + // client.Tags = defaultTags; client.CaptureMessage("Test", ErrorLevel.Info); var lastEvent = client.LastEvent(); @@ -227,7 +227,6 @@ public void CaptureMessage_OnlyMessageTags() private class TestableJsonPacketFactory : JsonPacketFactory { private readonly string project; - private JsonPacket m_lastEvent; public TestableJsonPacketFactory(string project) { @@ -244,20 +243,23 @@ protected override JsonPacket OnCreate(JsonPacket jsonPacket) private class TestableRavenClient : RavenClient { + private JsonPacket lastEvent; + + public TestableRavenClient(string dsn, IJsonPacketFactory jsonPacketFactory = null) : base(dsn, jsonPacketFactory) { } public JsonPacket LastEvent() { - return m_lastEvent; + return this.lastEvent; } protected override string Send(JsonPacket packet) { // TODO(dcramer): this is duped from RavenClient packet = PreparePacket(packet); - m_lastEvent = packet; + this.lastEvent = packet; return packet.Project; } From bec857470e58fe74e1c1478030ac89cd05946d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 13 Jan 2016 10:02:51 +0100 Subject: [PATCH 139/171] Made IRavenClient.Tags readonly, initialized by default and simplified tag merging. --- src/app/SharpRaven/IRavenClient.cs | 2 +- src/app/SharpRaven/RavenClient.cs | 64 +++++++++++++++--------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/app/SharpRaven/IRavenClient.cs b/src/app/SharpRaven/IRavenClient.cs index 33e410c3..dfb0cde0 100644 --- a/src/app/SharpRaven/IRavenClient.cs +++ b/src/app/SharpRaven/IRavenClient.cs @@ -76,7 +76,7 @@ public interface IRavenClient /// /// Default tags /// - IDictionary Tags { get; set; } + IDictionary Tags { get; } /// /// Gets or sets the timeout value in milliseconds for the diff --git a/src/app/SharpRaven/RavenClient.cs b/src/app/SharpRaven/RavenClient.cs index b49f5ec0..5c59b57d 100644 --- a/src/app/SharpRaven/RavenClient.cs +++ b/src/app/SharpRaven/RavenClient.cs @@ -2,21 +2,21 @@ // Copyright (c) 2014 The Sentry Team and individual contributors. // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are permitted // provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // 3. Neither the name of the Sentry nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR @@ -31,6 +31,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Net; using Newtonsoft.Json; @@ -47,6 +48,7 @@ namespace SharpRaven public partial class RavenClient : IRavenClient { private readonly Dsn currentDsn; + private readonly IDictionary defaultTags; private readonly IJsonPacketFactory jsonPacketFactory; private readonly ISentryRequestFactory sentryRequestFactory; private readonly ISentryUserFactory sentryUserFactory; @@ -63,6 +65,7 @@ public RavenClient(IJsonPacketFactory jsonPacketFactory = null) { } + /// /// Initializes a new instance of the class. /// @@ -102,7 +105,7 @@ public RavenClient(Dsn dsn, Logger = "root"; Timeout = TimeSpan.FromSeconds(5); - Tags = new Dictionary(); + this.defaultTags = new Dictionary(); } @@ -152,9 +155,12 @@ public Dsn CurrentDsn public string Environment { get; set; } /// - /// Default tags + /// Default tags sent on all events. /// - public IDictionary Tags { get; set; } + public IDictionary Tags + { + get { return this.defaultTags; } + } /// /// Gets or sets the timeout value in milliseconds for the HTTP communication with Sentry. @@ -209,7 +215,7 @@ public string CaptureException(Exception exception, string[] fingerprint = null, object extra = null) { - var finalTags = MergeDicts(Tags, tags); + var finalTags = MergeTags(tags); JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, exception, message, @@ -220,6 +226,7 @@ public string CaptureException(Exception exception, return Send(packet); } + /// /// Captures the message. /// @@ -237,7 +244,7 @@ public string CaptureMessage(SentryMessage message, string[] fingerprint = null, object extra = null) { - var finalTags = MergeDicts(Tags, tags); + var finalTags = MergeTags(tags); JsonPacket packet = this.jsonPacketFactory.Create(CurrentDsn.ProjectID, message, level, @@ -280,12 +287,12 @@ protected virtual string Send(JsonPacket packet) // generated packet packet = PreparePacket(packet); - var request = (HttpWebRequest)WebRequest.Create(currentDsn.SentryUri); + var request = (HttpWebRequest)WebRequest.Create(this.currentDsn.SentryUri); request.Timeout = (int)Timeout.TotalMilliseconds; request.ReadWriteTimeout = (int)Timeout.TotalMilliseconds; request.Method = "POST"; request.Accept = "application/json"; - request.Headers.Add("X-Sentry-Auth", PacketBuilder.CreateAuthenticationHeader(currentDsn)); + request.Headers.Add("X-Sentry-Auth", PacketBuilder.CreateAuthenticationHeader(this.currentDsn)); request.UserAgent = PacketBuilder.UserAgent; if (Compression) @@ -341,25 +348,6 @@ protected virtual string Send(JsonPacket packet) } } - private IDictionary MergeDicts(IDictionary one = null, IDictionary two = null) - { - var result = new Dictionary(); - if (one != null) { - foreach (KeyValuePair pair in one) { - result.Add(pair.Key, pair.Value); - } - } - if (two != null) { - foreach (KeyValuePair pair in two) { - if (result.ContainsKey(pair.Key)) { - result[pair.Key] = pair.Value; - } else { - result.Add(pair.Key, pair.Value); - } - } - } - return result; - } private string HandleException(Exception exception) { @@ -401,5 +389,17 @@ private string HandleException(Exception exception) return null; } + + + private IDictionary MergeTags(IDictionary tags = null) + { + if (tags == null) + return this.defaultTags; + + return this.defaultTags + .Where(kv => !tags.Keys.Contains(kv.Key)) + .Concat(tags) + .ToDictionary(kv => kv.Key, kv => kv.Value); + } } -} +} \ No newline at end of file From 490fb400790cd9508dd7c034fe7eadbdd9f2bd19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 13 Jan 2016 10:10:50 +0100 Subject: [PATCH 140/171] Removed dsn from doc --- src/app/SharpRaven/RavenClient.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/app/SharpRaven/RavenClient.cs b/src/app/SharpRaven/RavenClient.cs index 5c59b57d..80fb9dfd 100644 --- a/src/app/SharpRaven/RavenClient.cs +++ b/src/app/SharpRaven/RavenClient.cs @@ -271,13 +271,10 @@ protected virtual JsonPacket PreparePacket(JsonPacket packet) } - /// - /// Sends the specified packet to Sentry. - /// + /// Sends the specified packet to Sentry. /// The packet to send. - /// The Data Source Name in Sentry. /// - /// The of the successfully captured JSON packet, or null if it fails. + /// The of the successfully captured JSON packet, or null if it fails. /// protected virtual string Send(JsonPacket packet) { From 14b724b4221e44c153ee0a4fe0e0a11e357eebda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 13 Jan 2016 10:14:26 +0100 Subject: [PATCH 141/171] Let's not require C# 6 just yet. --- .../SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs index 73f7acd9..158e3f16 100644 --- a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs +++ b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs @@ -51,7 +51,10 @@ public class NancyContextJsonPacketFactory : JsonPacketFactory /// protected override JsonPacket OnCreate(JsonPacket jsonPacket) { - var nancyContextDataSlot = NancyConfiguration.Settings?.NancyContextDataSlot; + if (NancyConfiguration.Settings == null) + return jsonPacket; + + var nancyContextDataSlot = NancyConfiguration.Settings.NancyContextDataSlot; if (nancyContextDataSlot == null) return jsonPacket; From 05de40c749964277e6cc73142d5a7c837d4a8ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 13 Jan 2016 11:23:11 +0100 Subject: [PATCH 142/171] Made NancyConfiguration.NancyContextDataSlot and .SentryEventGuid into constants to avoid having to instantiate the configuration class unecessarily. --- .../Data/NancyContextJsonPacketFactory.cs | 9 +--- .../SharpRaven.Nancy/NancyConfiguration.cs | 41 ++++++++----------- .../SharpRaven.Nancy/SentryRequestStartup.cs | 15 ++++--- src/app/SharpRaven/Configuration.cs | 5 +-- .../SharpRaven.Nancy.UnitTests/NancyTests.cs | 2 +- 5 files changed, 30 insertions(+), 42 deletions(-) diff --git a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs index 158e3f16..bcd00892 100644 --- a/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs +++ b/src/app/SharpRaven.Nancy/Data/NancyContextJsonPacketFactory.cs @@ -51,14 +51,7 @@ public class NancyContextJsonPacketFactory : JsonPacketFactory /// protected override JsonPacket OnCreate(JsonPacket jsonPacket) { - if (NancyConfiguration.Settings == null) - return jsonPacket; - - var nancyContextDataSlot = NancyConfiguration.Settings.NancyContextDataSlot; - if (nancyContextDataSlot == null) - return jsonPacket; - - var nancyContext = CallContext.LogicalGetData(nancyContextDataSlot) as NancyContext; + var nancyContext = CallContext.LogicalGetData(NancyConfiguration.NancyContextDataSlot) as NancyContext; if (nancyContext == null) return jsonPacket; diff --git a/src/app/SharpRaven.Nancy/NancyConfiguration.cs b/src/app/SharpRaven.Nancy/NancyConfiguration.cs index e9400d0e..9cce83a7 100644 --- a/src/app/SharpRaven.Nancy/NancyConfiguration.cs +++ b/src/app/SharpRaven.Nancy/NancyConfiguration.cs @@ -28,7 +28,6 @@ #endregion -using System; using System.Configuration; namespace SharpRaven.Nancy @@ -41,6 +40,22 @@ public class NancyConfiguration : Configuration private const string CaptureExceptionOnErrorKey = "captureExceptionOnError"; private const string PipelineNameKey = "pipelineName"; + /// + /// Gets the nancy context data slot. + /// + /// + /// The nancy context data slot. + /// + public const string NancyContextDataSlot = "SharpRaven.Nancy.NancyContext"; + + /// + /// Gets the key for the GUID returned from Sentry after a successfully logged exception. + /// + /// + /// The key for the GUID returned from Sentry after a successfully logged exception. + /// + public const string SentryEventGuidKey = "SharpRaven.Nancy.SentryEventGuid"; + private static readonly NancyConfiguration settings = ConfigurationManager.GetSection("sharpRaven") as NancyConfiguration; @@ -56,17 +71,6 @@ public CaptureExceptionOnErrorElement CaptureExceptionOnError get { return (CaptureExceptionOnErrorElement)base[CaptureExceptionOnErrorKey]; } } - /// - /// Gets the nancy context data slot. - /// - /// - /// The nancy context data slot. - /// - public string NancyContextDataSlot - { - get { return "SharpRaven.Nancy.NancyContext"; } - } - /// /// Gets the <pipelineName /> configuration element. /// @@ -79,17 +83,6 @@ public PipelineNameElement PipelineName get { return (PipelineNameElement)base[PipelineNameKey]; } } - /// - /// Gets the key for the GUID returned from Sentry after a successfully logged exception. - /// - /// - /// The key for the GUID returned from Sentry after a successfully logged exception. - /// - public string SentryEventGuid - { - get { return "SharpRaven.Nancy.SentryEventGuid"; } - } - /// /// Gets the <sharpRaven/> configuration element. /// @@ -138,7 +131,7 @@ public class PipelineNameElement : ConfigurationElement /// The value of the the <pipelineName /> configuration element. /// [ConfigurationProperty("value", DefaultValue = "SharpRaven.Nancy")] - public String Value + public string Value { get { return (string)this["value"]; } set { this["value"] = value; } diff --git a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs index 521adfc9..3feaf66f 100644 --- a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs +++ b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs @@ -69,20 +69,23 @@ public SentryRequestStartup(IRavenClient ravenClient) public void Initialize(IPipelines pipelines, NancyContext context) { // on each request store the NancyContext to the LogicalCallContext - var nancyContextDataSlot = NancyConfiguration.Settings.NancyContextDataSlot; - CallContext.LogicalSetData(nancyContextDataSlot, context); + CallContext.LogicalSetData(NancyConfiguration.NancyContextDataSlot, context); - var name = NancyConfiguration.Settings.PipelineName.Value; + var nancyConfiguration = NancyConfiguration.Settings; + if (nancyConfiguration == null) + return; + + var name = nancyConfiguration.PipelineName.Value; var sharpRaven = new PipelineItem(name, (nancyContext, exception) => { - if (NancyConfiguration.Settings.CaptureExceptionOnError.Value) + if (nancyConfiguration.CaptureExceptionOnError.Value) { var guid = this.ravenClient.CaptureException(exception); if (guid != null) { - context.Items.Add(NancyConfiguration.Settings.SentryEventGuid, guid); - exception.Data.Add(NancyConfiguration.Settings.SentryEventGuid, guid); + context.Items.Add(NancyConfiguration.SentryEventGuidKey, guid); + exception.Data.Add(NancyConfiguration.SentryEventGuidKey, guid); } } diff --git a/src/app/SharpRaven/Configuration.cs b/src/app/SharpRaven/Configuration.cs index a6cb942b..4336d12c 100644 --- a/src/app/SharpRaven/Configuration.cs +++ b/src/app/SharpRaven/Configuration.cs @@ -28,7 +28,6 @@ #endregion -using System; using System.Configuration; namespace SharpRaven @@ -80,9 +79,9 @@ public class DsnElement : ConfigurationElement /// The value of the <dsn/> configuration element. /// [ConfigurationProperty("value")] - public String Value + public string Value { - get { return (String)this["value"]; } + get { return (string)this["value"]; } set { this["value"] = value; } } } diff --git a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs index cc4b9342..0b79e2b1 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs @@ -118,7 +118,7 @@ public void Post_InvokesRavenClientWithNancyContextJsonPacketFactory() var exception = Assert.Throws(throwing); // SentryRequestStartup.Initialize() should set the GUID in Exception.Data. @asbjornu - var loggedGuid = exception.Data[NancyConfiguration.Settings.SentryEventGuid]; + var loggedGuid = exception.Data[NancyConfiguration.SentryEventGuidKey]; Assert.That(loggedGuid, Is.EqualTo(guid)); } From 799071d5c4f0290c7efdbc851513f9f1228c176d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 13 Jan 2016 11:31:56 +0100 Subject: [PATCH 143/171] Upgraded from Nancy v1.3 to v1.4.3 --- .../SharpRaven.Nancy/SharpRaven.Nancy.csproj | 6 +++--- src/app/SharpRaven.Nancy/packages.config | 2 +- .../SharpRaven.Nancy.UnitTests/NancyTests.cs | 12 ++++++++---- .../SharpRaven.Nancy.UnitTests.csproj | 18 +++++++++--------- .../SharpRaven.Nancy.UnitTests/packages.config | 6 +++--- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj index b584953b..fd7af905 100644 --- a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj +++ b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj @@ -65,9 +65,9 @@ v4.5 - - False - ..\..\packages\Nancy.1.3.0\lib\net40\Nancy.dll + + ..\..\packages\Nancy.1.4.3\lib\net40\Nancy.dll + True False diff --git a/src/app/SharpRaven.Nancy/packages.config b/src/app/SharpRaven.Nancy/packages.config index eae9dac4..037a58d1 100644 --- a/src/app/SharpRaven.Nancy/packages.config +++ b/src/app/SharpRaven.Nancy/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs index 0b79e2b1..cd7111d1 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs @@ -85,9 +85,11 @@ public void Post_InvokesRavenClient() TestDelegate throwing = () => browser.Post("/"); - var exception = Assert.Throws(throwing); + var exception = Assert.Throws(throwing); - ravenClient.Received(1).CaptureException(exception); + Assert.That(exception.InnerException, Is.TypeOf()); + Assert.That(exception.InnerException.InnerException, Is.TypeOf()); + ravenClient.Received(1).CaptureException(exception.InnerException.InnerException); } @@ -115,10 +117,12 @@ public void Post_InvokesRavenClientWithNancyContextJsonPacketFactory() with.FormValue("GUID", guid); }); - var exception = Assert.Throws(throwing); + var exception = Assert.Throws(throwing); + Assert.That(exception.InnerException, Is.TypeOf()); + Assert.That(exception.InnerException.InnerException, Is.TypeOf()); // SentryRequestStartup.Initialize() should set the GUID in Exception.Data. @asbjornu - var loggedGuid = exception.Data[NancyConfiguration.SentryEventGuidKey]; + var loggedGuid = exception.InnerException.InnerException.Data[NancyConfiguration.SentryEventGuidKey]; Assert.That(loggedGuid, Is.EqualTo(guid)); } diff --git a/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj b/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj index f90c6d5b..c637f843 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj +++ b/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj @@ -61,17 +61,17 @@ ..\..\packages\CsQuery.1.3.4\lib\net40\CsQuery.dll - - False - ..\..\packages\Nancy.1.3.0\lib\net40\Nancy.dll + + ..\..\packages\Nancy.1.4.3\lib\net40\Nancy.dll + True - - False - ..\..\packages\Nancy.Hosting.Self.1.3.0\lib\net40\Nancy.Hosting.Self.dll + + ..\..\packages\Nancy.Hosting.Self.1.4.1\lib\net40\Nancy.Hosting.Self.dll + True - - False - ..\..\packages\Nancy.Testing.1.3.0\lib\net40\Nancy.Testing.dll + + ..\..\packages\Nancy.Testing.1.4.1\lib\net40\Nancy.Testing.dll + True ..\..\packages\NSubstitute.1.8.0.0\lib\net45\NSubstitute.dll diff --git a/src/tests/SharpRaven.Nancy.UnitTests/packages.config b/src/tests/SharpRaven.Nancy.UnitTests/packages.config index ccc2b075..fb24b70d 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/packages.config +++ b/src/tests/SharpRaven.Nancy.UnitTests/packages.config @@ -2,9 +2,9 @@ - - - + + + \ No newline at end of file From 2df1e455abe0a33c8cab2c9ee82d9298b542bd63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 13 Jan 2016 13:10:28 +0100 Subject: [PATCH 144/171] Move the IRavenClient from an instance registration to a type registration by making its lifetime transient; it can then be overridden in the application container. --- .../SharpRaven.Nancy/SentryRegistrations.cs | 20 ++++--------------- .../SharpRaven.Nancy.UnitTests/NancyTests.cs | 12 +++++------ 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/app/SharpRaven.Nancy/SentryRegistrations.cs b/src/app/SharpRaven.Nancy/SentryRegistrations.cs index b2bd4fc2..3c2124f7 100644 --- a/src/app/SharpRaven.Nancy/SentryRegistrations.cs +++ b/src/app/SharpRaven.Nancy/SentryRegistrations.cs @@ -58,17 +58,7 @@ public IEnumerable CollectionTypeRegistrations /// public IEnumerable InstanceRegistrations { - get - { - return new[] - { - //new InstanceRegistration(typeof(Dsn), new Dsn(Configuration.Settings.Dsn.Value)), - // TODO: I don't like to register the concrete instance like this, see the above TODO. @asbjornu - new InstanceRegistration(typeof(IRavenClient), - new RavenClient(new Dsn(NancyConfiguration.Settings.Dsn.Value), - new NancyContextJsonPacketFactory())), - }; - } + get { return null; } } /// @@ -81,12 +71,10 @@ public IEnumerable TypeRegistrations return new[] { new TypeRegistration(typeof(IJsonPacketFactory), - typeof(NancyContextJsonPacketFactory), - Lifetime.Singleton), - // TODO: I'd like to register the RavenClient like this so it's more composable and IoC friendly, but I'm seemingly unable to override their registration, which makes testing impossible. @asbjornu - /*new TypeRegistration(typeof(IRavenClient), + typeof(NancyContextJsonPacketFactory)), + new TypeRegistration(typeof(IRavenClient), typeof(RavenClient), - Lifetime.PerRequest),*/ + Lifetime.Transient) }; } } diff --git a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs index cd7111d1..b708eb44 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs @@ -2,21 +2,21 @@ // Copyright (c) 2014 The Sentry Team and individual contributors. // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are permitted // provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list of // conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. -// +// // 3. Neither the name of the Sentry nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR @@ -148,4 +148,4 @@ protected override string Send(JsonPacket packet) } } } -} +} \ No newline at end of file From 7a9aa8124d29eeb6249c8f1b4a6a91d3b8227d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 13 Jan 2016 13:18:35 +0100 Subject: [PATCH 145/171] Add test for injected DSN --- .../SharpRaven.Nancy/SentryRequestStartup.cs | 2 +- .../SharpRaven.Nancy.UnitTests/NancyTests.cs | 47 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs index 3feaf66f..be292395 100644 --- a/src/app/SharpRaven.Nancy/SentryRequestStartup.cs +++ b/src/app/SharpRaven.Nancy/SentryRequestStartup.cs @@ -68,7 +68,7 @@ public SentryRequestStartup(IRavenClient ravenClient) /// The current context public void Initialize(IPipelines pipelines, NancyContext context) { - // on each request store the NancyContext to the LogicalCallContext + // On each request, store the NancyContext in the LogicalCallContext CallContext.LogicalSetData(NancyConfiguration.NancyContextDataSlot, context); var nancyConfiguration = NancyConfiguration.Settings; diff --git a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs index b708eb44..ac5cdb28 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs @@ -93,6 +93,36 @@ public void Post_InvokesRavenClient() } + [Test] + public void Post_InvokesRavenClientWithInjectedDsn() + { + var dsn = "http://my:test@example.com/987123/oijf98j23r"; + var browser = new Browser(cfg => + { + cfg.Module(); + cfg.ApplicationStartup((container, pipelines) => + { + // Override the IRavenClient implementation so we don't perform + // any HTTP request and can retrieve the GUID so we can later + // assert that it is the same we sent in. @asbjornu + + container.Register(new Dsn(dsn)); + container.Register(); + }); + }); + + TestDelegate throwing = () => browser.Post("/"); + + var exception = Assert.Throws(throwing); + + Assert.That(exception.InnerException, Is.TypeOf()); + Assert.That(exception.InnerException.InnerException, Is.TypeOf()); + // SentryRequestStartup.Initialize() should set the return value from IRavenClient.Send() in Exception.Data. @asbjornu + var result = exception.InnerException.InnerException.Data[NancyConfiguration.SentryEventGuidKey]; + Assert.That(result, Is.EqualTo(dsn)); + } + + [Test] public void Post_InvokesRavenClientWithNancyContextJsonPacketFactory() { @@ -121,7 +151,7 @@ public void Post_InvokesRavenClientWithNancyContextJsonPacketFactory() Assert.That(exception.InnerException, Is.TypeOf()); Assert.That(exception.InnerException.InnerException, Is.TypeOf()); - // SentryRequestStartup.Initialize() should set the GUID in Exception.Data. @asbjornu + // SentryRequestStartup.Initialize() should set the return value from IRavenClient.Send() in Exception.Data. @asbjornu var loggedGuid = exception.InnerException.InnerException.Data[NancyConfiguration.SentryEventGuidKey]; Assert.That(loggedGuid, Is.EqualTo(guid)); } @@ -129,6 +159,9 @@ public void Post_InvokesRavenClientWithNancyContextJsonPacketFactory() private class TestableRavenClient : RavenClient { + private readonly Dsn dsn; + + public TestableRavenClient(IJsonPacketFactory jsonPacketFactory) : base(jsonPacketFactory) { @@ -137,8 +170,20 @@ public TestableRavenClient(IJsonPacketFactory jsonPacketFactory) } + public TestableRavenClient(Dsn dsn, IJsonPacketFactory jsonPacketFactory) + : base(dsn, jsonPacketFactory) + { + // This constructor must exist so Nancy can inject the Dsn and NancyContextJsonPacketFactory + // that is registered in SentryRegistrations. @asbjornu + this.dsn = dsn; + } + + protected override string Send(JsonPacket packet) { + if (this.dsn != null) + return this.dsn.ToString(); + // Retrieving the GUID from the JsonPacket verifies that // NancyContextJsonPacketFactory.OnCreate() has been invoked, // since it will copy the request data from the NancyContext. From 976b49ff948b75f0dfe60296f492d45cf60994f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 13 Jan 2016 13:41:11 +0100 Subject: [PATCH 146/171] Better commenting in the DSN test --- src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs index ac5cdb28..f6ff8f59 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs +++ b/src/tests/SharpRaven.Nancy.UnitTests/NancyTests.cs @@ -102,11 +102,12 @@ public void Post_InvokesRavenClientWithInjectedDsn() cfg.Module(); cfg.ApplicationStartup((container, pipelines) => { + // Register the DSN so we verify that it can be injected. @asbjornu + container.Register(new Dsn(dsn)); + // Override the IRavenClient implementation so we don't perform // any HTTP request and can retrieve the GUID so we can later // assert that it is the same we sent in. @asbjornu - - container.Register(new Dsn(dsn)); container.Register(); }); }); From f34e4f462d6fea002475e8db98367beffa6981a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Wed, 13 Jan 2016 14:17:31 +0100 Subject: [PATCH 147/171] Upgraded GitVersion from v3.1.2 to v3.3 --- src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj | 6 +++--- src/app/SharpRaven.Nancy/packages.config | 2 +- src/app/SharpRaven/SharpRaven.csproj | 6 +++--- src/app/SharpRaven/packages.config | 2 +- .../SharpRaven.Nancy.UnitTests.csproj | 6 +++--- src/tests/SharpRaven.Nancy.UnitTests/packages.config | 2 +- src/tests/SharpRaven.UnitTests/SharpRaven.UnitTests.csproj | 6 +++--- src/tests/SharpRaven.UnitTests/packages.config | 2 +- src/tests/SharpRaven.WebTest/SharpRaven.WebTest.csproj | 6 +++--- src/tests/SharpRaven.WebTest/packages.config | 4 ++-- 10 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj index fd7af905..94709efd 100644 --- a/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj +++ b/src/app/SharpRaven.Nancy/SharpRaven.Nancy.csproj @@ -13,7 +13,7 @@ 512 ..\ - fa2dde31 + 05c78a3e true @@ -102,11 +102,11 @@ - + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/src/app/SharpRaven.Nancy/packages.config b/src/app/SharpRaven.Nancy/packages.config index 037a58d1..adf4268e 100644 --- a/src/app/SharpRaven.Nancy/packages.config +++ b/src/app/SharpRaven.Nancy/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/src/app/SharpRaven/SharpRaven.csproj b/src/app/SharpRaven/SharpRaven.csproj index a1983e14..5f5cfea9 100644 --- a/src/app/SharpRaven/SharpRaven.csproj +++ b/src/app/SharpRaven/SharpRaven.csproj @@ -13,7 +13,7 @@ 512 ..\ - 56027b9c + 51b56455 true @@ -115,11 +115,11 @@ - + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/src/app/SharpRaven/packages.config b/src/app/SharpRaven/packages.config index 2ad8d41a..ffddf1af 100644 --- a/src/app/SharpRaven/packages.config +++ b/src/app/SharpRaven/packages.config @@ -1,5 +1,5 @@  - + diff --git a/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj b/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj index c637f843..7daf42b4 100644 --- a/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj +++ b/src/tests/SharpRaven.Nancy.UnitTests/SharpRaven.Nancy.UnitTests.csproj @@ -13,7 +13,7 @@ 512 true - 5b85eb88 + c36e810a bin\Release\net40\ @@ -122,12 +122,12 @@ - + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + - \ No newline at end of file + From e4e90c6e72d33e1cf2cbf4940889671f071d9c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Saulius=20Menkevi=C4=8Dius?= Date: Fri, 22 Jan 2016 13:34:40 +0200 Subject: [PATCH 170/171] Makefile: add `--debug' switch when running tests on mono in order to get better stack traces --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fe6c4f0b..52b4c15e 100644 --- a/Makefile +++ b/Makefile @@ -9,4 +9,4 @@ restore: test: restore xbuild "./src/SharpRaven.build" - mono --runtime=v4.0.30319 ./src/packages/NUnit.Runners.2.6.4/tools/nunit-console.exe ./src/tests/SharpRaven.UnitTests/bin/Release/net45/SharpRaven.UnitTests.dll -exclude=NuGet,NoMono -nodots + mono --debug --runtime=v4.0.30319 ./src/packages/NUnit.Runners.2.6.4/tools/nunit-console.exe ./src/tests/SharpRaven.UnitTests/bin/Release/net45/SharpRaven.UnitTests.dll -exclude=NuGet,NoMono -nodots From a41a2aa42bc295e46cde333b68a894e60002f828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Ulsberg?= Date: Tue, 26 Jan 2016 10:26:58 +0100 Subject: [PATCH 171/171] Let's set the next version to 2.0 --- GitVersionConfig.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/GitVersionConfig.yaml b/GitVersionConfig.yaml index 7b84a296..3156c744 100644 --- a/GitVersionConfig.yaml +++ b/GitVersionConfig.yaml @@ -1,3 +1,4 @@ +next-version: 2.0 branches: feature[/-]: mode: ContinuousDeployment