Skip to content

Commit 00779cb

Browse files
authored
Merge pull request #189 from getsentry/ref/extend-stacktrace-factory
ref: stacktrace factory extensibility
2 parents 50444e5 + 042a506 commit 00779cb

File tree

9 files changed

+55
-33
lines changed

9 files changed

+55
-33
lines changed

src/Sentry/Extensibility/ISentryStackTraceFactory.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,16 @@
33

44
namespace Sentry.Extensibility
55
{
6+
/// <summary>
7+
/// Factory to <see cref="SentryStackTrace" /> from an <see cref="Exception" />.
8+
/// </summary>
69
public interface ISentryStackTraceFactory
710
{
11+
/// <summary>
12+
/// Creates a <see cref="SentryStackTrace" /> from the optional <see cref="Exception" />.
13+
/// </summary>
14+
/// <param name="exception">The exception to create the stacktrace from.</param>
15+
/// <returns>A Sentry stack trace.</returns>
816
SentryStackTrace Create(Exception exception = null);
917
}
1018
}

src/Sentry/Extensibility/SentryStackTraceFactory.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,20 @@
88

99
namespace Sentry.Extensibility
1010
{
11+
/// <summary>
12+
/// Default factory to <see cref="SentryStackTrace" /> from an <see cref="Exception" />.
13+
/// </summary>
1114
public class SentryStackTraceFactory : ISentryStackTraceFactory
1215
{
1316
private readonly SentryOptions _options;
1417

1518
public SentryStackTraceFactory(SentryOptions options) => _options = options;
1619

20+
/// <summary>
21+
/// Creates a <see cref="SentryStackTrace" /> from the optional <see cref="Exception" />.
22+
/// </summary>
23+
/// <param name="exception">The exception to create the stacktrace from.</param>
24+
/// <returns>A Sentry stack trace.</returns>
1725
public SentryStackTrace Create(Exception exception = null)
1826
{
1927
var isCurrentStackTrace = exception == null && _options.AttachStacktrace;

src/Sentry/Internal/MainExceptionProcessor.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ namespace Sentry.Internal
1111
internal class MainExceptionProcessor : ISentryEventExceptionProcessor
1212
{
1313
private readonly SentryOptions _options;
14-
private readonly ISentryStackTraceFactory _sentryStackTraceFactory;
14+
internal Func<ISentryStackTraceFactory> SentryStackTraceFactoryAccessor { get; }
1515

16-
public MainExceptionProcessor(SentryOptions options, ISentryStackTraceFactory sentryStackTraceFactory)
16+
public MainExceptionProcessor(SentryOptions options, Func<ISentryStackTraceFactory> sentryStackTraceFactoryAccessor)
1717
{
1818
Debug.Assert(options != null);
19-
Debug.Assert(sentryStackTraceFactory != null);
19+
Debug.Assert(sentryStackTraceFactoryAccessor != null);
2020
_options = options;
21-
_sentryStackTraceFactory = sentryStackTraceFactory;
21+
SentryStackTraceFactoryAccessor = sentryStackTraceFactoryAccessor;
2222
}
2323

2424
public void Process(Exception exception, SentryEvent sentryEvent)
@@ -101,7 +101,7 @@ internal IEnumerable<SentryException> CreateSentryException(Exception exception)
101101
}
102102
}
103103

104-
sentryEx.Stacktrace = _sentryStackTraceFactory.Create(exception);
104+
sentryEx.Stacktrace = SentryStackTraceFactoryAccessor().Create(exception);
105105

106106
yield return sentryEx;
107107
}

src/Sentry/Internal/MainSentryEventProcessor.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,19 @@ private static readonly (string Name, string Version) NameAndVersion
3232
private static readonly string ProtocolPackageName = "nuget:" + NameAndVersion.Name;
3333

3434
private readonly SentryOptions _options;
35-
private readonly ISentryStackTraceFactory _sentryStackTraceFactory;
35+
internal Func<ISentryStackTraceFactory> SentryStackTraceFactoryAccessor { get; }
3636

3737
internal string Release => _release.Value;
3838
internal Runtime Runtime => _runtime.Value;
3939

4040
public MainSentryEventProcessor(
4141
SentryOptions options,
42-
ISentryStackTraceFactory sentryStackTraceFactory)
42+
Func<ISentryStackTraceFactory> sentryStackTraceFactoryAccessor)
4343
{
4444
Debug.Assert(options != null);
45-
Debug.Assert(sentryStackTraceFactory != null);
45+
Debug.Assert(sentryStackTraceFactoryAccessor != null);
4646
_options = options;
47-
_sentryStackTraceFactory = sentryStackTraceFactory;
47+
SentryStackTraceFactoryAccessor = sentryStackTraceFactoryAccessor;
4848
}
4949

5050
public SentryEvent Process(SentryEvent @event)
@@ -104,7 +104,7 @@ public SentryEvent Process(SentryEvent @event)
104104

105105
if (@event.Exception == null)
106106
{
107-
var stackTrace = _sentryStackTraceFactory.Create(@event.Exception);
107+
var stackTrace = SentryStackTraceFactoryAccessor().Create(@event.Exception);
108108
if (stackTrace != null)
109109
{
110110
@event.Stacktrace = stackTrace;

src/Sentry/SentryOptions.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ namespace Sentry
2222
/// </summary>
2323
public class SentryOptions : IScopeOptions
2424
{
25+
private readonly Func<ISentryStackTraceFactory> _sentryStackTraceFactoryAccessor;
26+
internal ISentryStackTraceFactory SentryStackTraceFactory { get; set; }
27+
2528
internal string ClientVersion { get; } = SdkName;
2629

2730
internal int SentryVersion { get; } = ProtocolVersion;
@@ -332,12 +335,14 @@ public SentryOptions()
332335
= ImmutableList.Create<Func<IEnumerable<ISentryEventExceptionProcessor>>>(
333336
() => ExceptionProcessors);
334337

335-
var sentryStackTraceFactory = new SentryStackTraceFactory(this);
338+
SentryStackTraceFactory = new SentryStackTraceFactory(this);
339+
_sentryStackTraceFactoryAccessor = () => SentryStackTraceFactory;
340+
336341
EventProcessors
337342
= ImmutableList.Create<ISentryEventProcessor>(
338343
// de-dupe to be the first to run
339344
new DuplicateEventDetectionEventProcessor(this),
340-
new MainSentryEventProcessor(this, sentryStackTraceFactory));
345+
new MainSentryEventProcessor(this, _sentryStackTraceFactoryAccessor));
341346

342347
#if SYSTEM_WEB
343348
EventProcessors = EventProcessors.Add(
@@ -355,7 +360,7 @@ public SentryOptions()
355360

356361
ExceptionProcessors
357362
= ImmutableList.Create<ISentryEventExceptionProcessor>(
358-
new MainExceptionProcessor(this, sentryStackTraceFactory));
363+
new MainExceptionProcessor(this, _sentryStackTraceFactoryAccessor));
359364

360365
Integrations
361366
= ImmutableList.Create<ISdkIntegration>(

src/Sentry/SentryOptionsExtensions.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,12 @@ public static IEnumerable<ISentryEventExceptionProcessor> GetAllExceptionProcess
127127
/// <param name="sentryStackTraceFactory">The stack trace factory.</param>
128128
public static SentryOptions UseStackTraceFactory(this SentryOptions options, ISentryStackTraceFactory sentryStackTraceFactory)
129129
{
130-
if (sentryStackTraceFactory == null) throw new ArgumentNullException(nameof(sentryStackTraceFactory));
131-
132-
options.EventProcessors = options.EventProcessors.RemoveAt(1)
133-
.Insert(1, new MainSentryEventProcessor(options, sentryStackTraceFactory));
130+
if (sentryStackTraceFactory == null)
131+
{
132+
throw new ArgumentNullException(nameof(sentryStackTraceFactory));
133+
}
134134

135-
options.ExceptionProcessors = options.ExceptionProcessors.RemoveAt(0)
136-
.Insert(0, new MainExceptionProcessor(options, sentryStackTraceFactory));
135+
options.SentryStackTraceFactory = sentryStackTraceFactory;
137136

138137
return options;
139138
}

test/Sentry.Tests/Internals/MainExceptionProcessorTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ private class Fixture
1313
{
1414
public ISentryStackTraceFactory SentryStackTraceFactory { get; set; } = Substitute.For<ISentryStackTraceFactory>();
1515
public SentryOptions SentryOptions { get; set; } = new SentryOptions();
16-
public MainExceptionProcessor GetSut() => new MainExceptionProcessor(SentryOptions, SentryStackTraceFactory);
16+
public MainExceptionProcessor GetSut() => new MainExceptionProcessor(SentryOptions, () => SentryStackTraceFactory);
1717
}
1818

1919
private readonly Fixture _fixture = new Fixture();

test/Sentry.Tests/Internals/MainSentryEventProcessorTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ private class Fixture
1616
{
1717
public ISentryStackTraceFactory SentryStackTraceFactory { get; set; } = Substitute.For<ISentryStackTraceFactory>();
1818
public SentryOptions SentryOptions { get; set; } = new SentryOptions();
19-
public MainSentryEventProcessor GetSut() => new MainSentryEventProcessor(SentryOptions, SentryStackTraceFactory);
19+
public MainSentryEventProcessor GetSut() => new MainSentryEventProcessor(SentryOptions, () => SentryStackTraceFactory);
2020
}
2121

2222
private readonly Fixture _fixture = new Fixture();

test/Sentry.Tests/SentryOptionsExtensionsTests.cs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -189,23 +189,25 @@ public void GetAllEventProcessors_NoAdding_SecondReturned_MainSentryEventProcess
189189
}
190190

191191
[Fact]
192-
public void UseStackTraceFactory()
192+
public void UseStackTraceFactory_ReplacesStackTraceFactory()
193193
{
194-
var eventProcessor1 = Sut.GetAllEventProcessors().Skip(1).First();
195-
var exceptionProcessor1 = Sut.GetAllExceptionProcessors().First();
194+
var expected = Substitute.For<ISentryStackTraceFactory>();
195+
Sut.UseStackTraceFactory(expected);
196196

197-
Sut.UseStackTraceFactory(Substitute.For<ISentryStackTraceFactory>());
197+
Assert.Same(expected, Sut.SentryStackTraceFactory);
198+
}
198199

199-
var eventProcessor2 = Sut.GetAllEventProcessors().Skip(1).First();
200-
var exceptionProcessor2 = Sut.GetAllExceptionProcessors().First();
200+
[Fact]
201+
public void UseStackTraceFactory_ReplacesStackTraceFactory_InCurrentProcessors()
202+
{
203+
var eventProcessor = Sut.GetAllEventProcessors().OfType<MainSentryEventProcessor>().Single();
204+
var exceptionProcessor = Sut.GetAllExceptionProcessors().OfType<MainExceptionProcessor>().Single();
201205

202-
Assert.IsType<MainSentryEventProcessor>(eventProcessor1);
203-
Assert.IsType<MainExceptionProcessor>(exceptionProcessor1);
204-
Assert.IsType<MainSentryEventProcessor>(eventProcessor2);
205-
Assert.IsType<MainExceptionProcessor>(exceptionProcessor2);
206+
var expected = Substitute.For<ISentryStackTraceFactory>();
207+
Sut.UseStackTraceFactory(expected);
206208

207-
Assert.NotEqual(eventProcessor1, eventProcessor2);
208-
Assert.NotEqual(exceptionProcessor1, exceptionProcessor2);
209+
Assert.Same(expected, eventProcessor.SentryStackTraceFactoryAccessor());
210+
Assert.Same(expected, exceptionProcessor.SentryStackTraceFactoryAccessor());
209211
}
210212

211213
[Fact]

0 commit comments

Comments
 (0)