Skip to content

Commit 68a9976

Browse files
Merge branch 'main' into feedback
2 parents 39ca97f + fbdcce9 commit 68a9976

15 files changed

+318
-54
lines changed

CHANGELOG.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,27 @@
22

33
## Unreleased
44

5+
56
### Features
67

78
- User Feedback can now be captured without errors/exceptions. Note that these APIs replace the older UserFeedback APIs, which have now been marked as obsolete (and will be removed in a future major version bump) ([#3981](https://github.com/getsentry/sentry-dotnet/pull/3981))
9+
- Users can now register their own MAUI controls for breadcrumb creation ([#3997](https://github.com/getsentry/sentry-dotnet/pull/3997))
810
- Serilog scope properties are now sent with Sentry events ([#3976](https://github.com/getsentry/sentry-dotnet/pull/3976))
911
- The sample seed used for sampling decisions is now propagated, for use in downstream custom trace samplers ([#3951](https://github.com/getsentry/sentry-dotnet/pull/3951))
12+
- Add Azure Function UseSentry overloads for easier wire ups ([#3971](https://github.com/getsentry/sentry-dotnet/pull/3971))
1013

1114
### Fixes
1215

13-
- Add Azure Function UseSentry overloads for easier wire ups ([#3971](https://github.com/getsentry/sentry-dotnet/pull/3971))
16+
- Fix mismapped breadcrumb levels coming in from native to dotnet SDK ([#3993](https://github.com/getsentry/sentry-dotnet/pull/3993))
1417

1518
### Dependencies
1619

17-
- Bump CLI from v2.41.1 to v2.42.1 ([#3979](https://github.com/getsentry/sentry-dotnet/pull/3979))
18-
- [changelog](https://github.com/getsentry/sentry-cli/blob/master/CHANGELOG.md#2421)
19-
- [diff](https://github.com/getsentry/sentry-cli/compare/2.41.1...2.42.1)
20+
- Bump CLI from v2.41.1 to v2.42.2 ([#3979](https://github.com/getsentry/sentry-dotnet/pull/3979), [#4002](https://github.com/getsentry/sentry-dotnet/pull/4002))
21+
- [changelog](https://github.com/getsentry/sentry-cli/blob/master/CHANGELOG.md#2422)
22+
- [diff](https://github.com/getsentry/sentry-cli/compare/2.41.1...2.42.2)
23+
- Bump Native SDK from v0.7.20 to v0.8.0 ([#4003](https://github.com/getsentry/sentry-dotnet/pull/4003))
24+
- [changelog](https://github.com/getsentry/sentry-native/blob/master/CHANGELOG.md#080)
25+
- [diff](https://github.com/getsentry/sentry-native/compare/0.7.20...0.8.0)
2026

2127
## 5.1.1
2228

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383

8484
<!-- Set the version and local path for Sentry CLI (downloaded in the restore phase of Sentry.csproj) -->
8585
<PropertyGroup Condition="'$(SolutionName)' != 'Sentry.Unity'">
86-
<SentryCLIVersion>2.42.1</SentryCLIVersion>
86+
<SentryCLIVersion>2.42.2</SentryCLIVersion>
8787
<SentryCLIDirectory>$(MSBuildThisFileDirectory)tools\sentry-cli\$(SentryCLIVersion)\</SentryCLIDirectory>
8888
</PropertyGroup>
8989

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
namespace Sentry.Maui;
2+
3+
/// <summary>
4+
/// Bind to MAUI controls to generate breadcrumbs and other metrics
5+
/// </summary>
6+
public interface IMauiElementEventBinder
7+
{
8+
/// <summary>
9+
/// Bind to an element
10+
/// </summary>
11+
/// <param name="element"></param>
12+
/// <param name="addBreadcrumb">
13+
/// This adds a breadcrumb to the sentry hub
14+
/// NOTE: we will override the type, timestamp, and category of the breadcrumb
15+
/// </param>
16+
void Bind(VisualElement element, Action<BreadcrumbEvent> addBreadcrumb);
17+
18+
/// <summary>
19+
/// Unbind the element because MAUI is removing the page
20+
/// </summary>
21+
/// <param name="element"></param>
22+
void UnBind(VisualElement element);
23+
}
24+
25+
/// <summary>
26+
/// Breadcrumb arguments
27+
/// </summary>
28+
/// <param name="Sender"></param>
29+
/// <param name="EventName"></param>
30+
/// <param name="ExtraData"></param>
31+
public record BreadcrumbEvent(
32+
object? Sender,
33+
string EventName,
34+
params IEnumerable<(string Key, string Value)>[] ExtraData
35+
);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
namespace Sentry.Maui.Internal;
2+
3+
/// <inheritdoc />
4+
public class MauiButtonEventsBinder : IMauiElementEventBinder
5+
{
6+
private Action<BreadcrumbEvent>? addBreadcrumbCallback;
7+
8+
/// <inheritdoc />
9+
public void Bind(VisualElement element, Action<BreadcrumbEvent> addBreadcrumb)
10+
{
11+
addBreadcrumbCallback = addBreadcrumb;
12+
13+
if (element is Button button)
14+
{
15+
button.Clicked += OnButtonOnClicked;
16+
button.Pressed += OnButtonOnPressed;
17+
button.Released += OnButtonOnReleased;
18+
}
19+
}
20+
21+
/// <inheritdoc />
22+
public void UnBind(VisualElement element)
23+
{
24+
if (element is Button button)
25+
{
26+
button.Clicked -= OnButtonOnClicked;
27+
button.Pressed -= OnButtonOnPressed;
28+
button.Released -= OnButtonOnReleased;
29+
}
30+
}
31+
32+
33+
private void OnButtonOnClicked(object? sender, EventArgs _)
34+
=> addBreadcrumbCallback?.Invoke(new(sender, nameof(Button.Clicked)));
35+
36+
private void OnButtonOnPressed(object? sender, EventArgs _)
37+
=> addBreadcrumbCallback?.Invoke(new(sender, nameof(Button.Pressed)));
38+
39+
private void OnButtonOnReleased(object? sender, EventArgs _)
40+
=> addBreadcrumbCallback?.Invoke(new(sender, nameof(Button.Released)));
41+
}

src/Sentry.Maui/Internal/MauiEventsBinder.cs

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ internal class MauiEventsBinder : IMauiEventsBinder
1111
{
1212
private readonly IHub _hub;
1313
private readonly SentryMauiOptions _options;
14+
private readonly IEnumerable<IMauiElementEventBinder> _elementEventBinders;
1415

1516
// https://develop.sentry.dev/sdk/event-payloads/breadcrumbs/#breadcrumb-types
1617
// https://github.com/getsentry/sentry/blob/master/static/app/types/breadcrumbs.tsx
@@ -22,10 +23,11 @@ internal class MauiEventsBinder : IMauiEventsBinder
2223
internal const string RenderingCategory = "ui.rendering";
2324
internal const string UserActionCategory = "ui.useraction";
2425

25-
public MauiEventsBinder(IHub hub, IOptions<SentryMauiOptions> options)
26+
public MauiEventsBinder(IHub hub, IOptions<SentryMauiOptions> options, IEnumerable<IMauiElementEventBinder> elementEventBinders)
2627
{
2728
_hub = hub;
2829
_options = options.Value;
30+
_elementEventBinders = elementEventBinders;
2931
}
3032

3133
public void HandleApplicationEvents(Application application, bool bind = true)
@@ -70,7 +72,7 @@ public void HandleApplicationEvents(Application application, bool bind = true)
7072
}
7173
}
7274

73-
private void OnApplicationOnDescendantAdded(object? _, ElementEventArgs e)
75+
internal void OnApplicationOnDescendantAdded(object? _, ElementEventArgs e)
7476
{
7577
if (_options.CreateElementEventsBreadcrumbs)
7678
{
@@ -96,15 +98,30 @@ private void OnApplicationOnDescendantAdded(object? _, ElementEventArgs e)
9698
case Page page:
9799
HandlePageEvents(page);
98100
break;
99-
case Button button:
100-
HandleButtonEvents(button);
101+
default:
102+
if (e.Element is VisualElement ve)
103+
{
104+
foreach (var binder in _elementEventBinders)
105+
{
106+
binder.Bind(ve, OnBreadcrumbCreateCallback);
107+
}
108+
}
101109
break;
102-
103-
// TODO: Attach to specific events on more control types
104110
}
105111
}
106112

107-
private void OnApplicationOnDescendantRemoved(object? _, ElementEventArgs e)
113+
internal void OnBreadcrumbCreateCallback(BreadcrumbEvent breadcrumb)
114+
{
115+
_hub.AddBreadcrumbForEvent(
116+
_options,
117+
breadcrumb.Sender,
118+
breadcrumb.EventName,
119+
UserType,
120+
UserActionCategory
121+
);
122+
}
123+
124+
internal void OnApplicationOnDescendantRemoved(object? _, ElementEventArgs e)
108125
{
109126
// All elements have a set of common events we can hook
110127
HandleElementEvents(e.Element, bind: false);
@@ -127,8 +144,14 @@ private void OnApplicationOnDescendantRemoved(object? _, ElementEventArgs e)
127144
case Page page:
128145
HandlePageEvents(page, bind: false);
129146
break;
130-
case Button button:
131-
HandleButtonEvents(button, bind: false);
147+
default:
148+
if (e.Element is VisualElement ve)
149+
{
150+
foreach (var binder in _elementEventBinders)
151+
{
152+
binder.UnBind(ve);
153+
}
154+
}
132155
break;
133156
}
134157
}
@@ -279,22 +302,6 @@ internal void HandlePageEvents(Page page, bool bind = true)
279302
}
280303
}
281304

282-
internal void HandleButtonEvents(Button button, bool bind = true)
283-
{
284-
if (bind)
285-
{
286-
button.Clicked += OnButtonOnClicked;
287-
button.Pressed += OnButtonOnPressed;
288-
button.Released += OnButtonOnReleased;
289-
}
290-
else
291-
{
292-
button.Clicked -= OnButtonOnClicked;
293-
button.Pressed -= OnButtonOnPressed;
294-
button.Released -= OnButtonOnReleased;
295-
}
296-
}
297-
298305
// Application Events
299306

300307
private void OnApplicationOnPageAppearing(object? sender, Page page) =>
@@ -424,15 +431,4 @@ private void OnPageOnNavigatedTo(object? sender, NavigatedToEventArgs e) =>
424431

425432
private void OnPageOnLayoutChanged(object? sender, EventArgs _) =>
426433
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Page.LayoutChanged), SystemType, RenderingCategory);
427-
428-
// Button Events
429-
430-
private void OnButtonOnClicked(object? sender, EventArgs _) =>
431-
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Button.Clicked), UserType, UserActionCategory);
432-
433-
private void OnButtonOnPressed(object? sender, EventArgs _) =>
434-
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Button.Pressed), UserType, UserActionCategory);
435-
436-
private void OnButtonOnReleased(object? sender, EventArgs _) =>
437-
_hub.AddBreadcrumbForEvent(_options, sender, nameof(Button.Released), UserType, UserActionCategory);
438434
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
namespace Sentry.Maui.Internal;
2+
3+
/// <inheritdoc />
4+
public class MauiImageButtonEventsBinder : IMauiElementEventBinder
5+
{
6+
private Action<BreadcrumbEvent>? addBreadcrumbCallback;
7+
8+
/// <inheritdoc />
9+
public void Bind(VisualElement element, Action<BreadcrumbEvent> addBreadcrumb)
10+
{
11+
addBreadcrumbCallback = addBreadcrumb;
12+
13+
if (element is ImageButton image)
14+
{
15+
image.Clicked += OnButtonOnClicked;
16+
image.Pressed += OnButtonOnPressed;
17+
image.Released += OnButtonOnReleased;
18+
}
19+
}
20+
21+
/// <inheritdoc />
22+
public void UnBind(VisualElement element)
23+
{
24+
if (element is ImageButton image)
25+
{
26+
image.Clicked -= OnButtonOnClicked;
27+
image.Pressed -= OnButtonOnPressed;
28+
image.Released -= OnButtonOnReleased;
29+
}
30+
}
31+
32+
33+
private void OnButtonOnClicked(object? sender, EventArgs _)
34+
=> addBreadcrumbCallback?.Invoke(new(sender, nameof(ImageButton.Clicked)));
35+
36+
private void OnButtonOnPressed(object? sender, EventArgs _)
37+
=> addBreadcrumbCallback?.Invoke(new(sender, nameof(ImageButton.Pressed)));
38+
39+
private void OnButtonOnReleased(object? sender, EventArgs _)
40+
=> addBreadcrumbCallback?.Invoke(new(sender, nameof(ImageButton.Released)));
41+
}

src/Sentry.Maui/SentryMauiAppBuilderExtensions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ public static MauiAppBuilder UseSentry(this MauiAppBuilder builder,
5454
services.AddSingleton<IMauiInitializeService, SentryMauiInitializer>();
5555
services.AddSingleton<IConfigureOptions<SentryMauiOptions>, SentryMauiOptionsSetup>();
5656
services.AddSingleton<Disposer>();
57+
58+
services.AddSingleton<IMauiElementEventBinder, MauiButtonEventsBinder>();
59+
services.AddSingleton<IMauiElementEventBinder, MauiImageButtonEventsBinder>();
5760
services.TryAddSingleton<IMauiEventsBinder, MauiEventsBinder>();
5861

5962
services.AddSentry<SentryMauiOptions>();

src/Sentry/Breadcrumb.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,18 @@ public static Breadcrumb FromJson(JsonElement json)
157157
var type = json.GetPropertyOrNull("type")?.GetString();
158158
var data = json.GetPropertyOrNull("data")?.GetStringDictionaryOrNull();
159159
var category = json.GetPropertyOrNull("category")?.GetString();
160-
var level = json.GetPropertyOrNull("level")?.GetString()?.ParseEnum<BreadcrumbLevel>() ?? default;
161160

161+
var levelString = json.GetPropertyOrNull("level")?.GetString();
162+
var level = levelString?.ToUpper() switch
163+
{
164+
"DEBUG" => BreadcrumbLevel.Debug,
165+
"INFO" => BreadcrumbLevel.Info,
166+
"WARNING" => BreadcrumbLevel.Warning,
167+
"ERROR" => BreadcrumbLevel.Error,
168+
"CRITICAL" => BreadcrumbLevel.Critical,
169+
"FATAL" => BreadcrumbLevel.Critical,
170+
_ => default
171+
};
162172
return new Breadcrumb(timestamp, message, type, data!, category, level);
163173
}
164174
}

src/Sentry/Sentry.csproj

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,13 @@
120120
<_OSArchitecture>$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)</_OSArchitecture>
121121
</PropertyGroup>
122122
<ItemGroup>
123-
<SentryCLIDownload Condition="'$(CI_PUBLISHING_BUILD)' == 'true' Or ($([MSBuild]::IsOSPlatform('OSX')) And $(_OSArchitecture) == 'Arm64')" Include="sentry-cli-Darwin-arm64" FileHash="791294ec6f10cab022293c4c7daf5fe0faf8b6e503ba6a0a266bed869aa9b7af" />
124-
<SentryCLIDownload Condition="'$(CI_PUBLISHING_BUILD)' == 'true' Or ($([MSBuild]::IsOSPlatform('OSX')) And $(_OSArchitecture) == 'X64')" Include="sentry-cli-Darwin-x86_64" FileHash="4a9e6b18fd69a7d4318fa5e31f779e46f987ffe6e04f70c30a9bd2481ec4d70f" />
125-
<SentryCLIDownload Condition="'$(CI_PUBLISHING_BUILD)' == 'true' Or ($([MSBuild]::IsOSPlatform('Linux')) And $(_OSArchitecture) == 'Arm64')" Include="sentry-cli-Linux-aarch64" FileHash="672fe1d63d6ebbf4b8c59c43e1b75869367378f05088843cf6641562a8c446e2" />
126-
<SentryCLIDownload Condition="'$(CI_PUBLISHING_BUILD)' == 'true' Or ($([MSBuild]::IsOSPlatform('Linux')) And $(_OSArchitecture) == 'X86')" Include="sentry-cli-Linux-i686" FileHash="41ff53c447175252ef179852157b2e01a2dac256b72257b69fff214b13b93e7c" />
127-
<SentryCLIDownload Condition="'$(CI_PUBLISHING_BUILD)' == 'true' Or ($([MSBuild]::IsOSPlatform('Linux')) And $(_OSArchitecture) == 'X64')" Include="sentry-cli-Linux-x86_64" FileHash="b9d7e2471e7860323f77c6417b6e402c49deacba0f961429a1b95dd245fb9607" />
128-
<SentryCLIDownload Condition="'$(CI_PUBLISHING_BUILD)' == 'true' Or ($([MSBuild]::IsOSPlatform('Windows')) And $(_OSArchitecture) == 'X86')" Include="sentry-cli-Windows-i686.exe" FileHash="ec1bcd834cc7d32c8ce25ae9fea45382f8be99350c031afa0367a86de416dcc0" />
129-
<SentryCLIDownload Condition="'$(CI_PUBLISHING_BUILD)' == 'true' Or ($([MSBuild]::IsOSPlatform('Windows')) And $(_OSArchitecture) != 'X86')" Include="sentry-cli-Windows-x86_64.exe" FileHash="b91e32da326b28739ad2252219db1fa3ddd8b3e4183ff8d174420b9d97bddbbf" />
123+
<SentryCLIDownload Condition="'$(CI_PUBLISHING_BUILD)' == 'true' Or ($([MSBuild]::IsOSPlatform('OSX')) And $(_OSArchitecture) == 'Arm64')" Include="sentry-cli-Darwin-arm64" FileHash="0443a228db1b8fddd4cade3c9b7d8ac4ea46c9872fcbaa46014f95f6c25f7d97" />
124+
<SentryCLIDownload Condition="'$(CI_PUBLISHING_BUILD)' == 'true' Or ($([MSBuild]::IsOSPlatform('OSX')) And $(_OSArchitecture) == 'X64')" Include="sentry-cli-Darwin-x86_64" FileHash="f95c7a2b7555bf41d54904cedd1be6c1b7b2765eff4e2a8a5911fda2af7fa761" />
125+
<SentryCLIDownload Condition="'$(CI_PUBLISHING_BUILD)' == 'true' Or ($([MSBuild]::IsOSPlatform('Linux')) And $(_OSArchitecture) == 'Arm64')" Include="sentry-cli-Linux-aarch64" FileHash="5b0eae7991817bb58ec9a039fdec38cace47c40f5133e11f553985968dc74af6" />
126+
<SentryCLIDownload Condition="'$(CI_PUBLISHING_BUILD)' == 'true' Or ($([MSBuild]::IsOSPlatform('Linux')) And $(_OSArchitecture) == 'X86')" Include="sentry-cli-Linux-i686" FileHash="345926403c9e3c58d39b4938eee43299966e6984fc1ba3030ad21932d498b8bf" />
127+
<SentryCLIDownload Condition="'$(CI_PUBLISHING_BUILD)' == 'true' Or ($([MSBuild]::IsOSPlatform('Linux')) And $(_OSArchitecture) == 'X64')" Include="sentry-cli-Linux-x86_64" FileHash="7d5e69080cac84468547796a1123a2db05133dc4da5b4b042f5f1b5f32050cc5" />
128+
<SentryCLIDownload Condition="'$(CI_PUBLISHING_BUILD)' == 'true' Or ($([MSBuild]::IsOSPlatform('Windows')) And $(_OSArchitecture) == 'X86')" Include="sentry-cli-Windows-i686.exe" FileHash="8a9d33e406563f497df418b3c98094b7c0534d393349fd0e94feba7f8e85c006" />
129+
<SentryCLIDownload Condition="'$(CI_PUBLISHING_BUILD)' == 'true' Or ($([MSBuild]::IsOSPlatform('Windows')) And $(_OSArchitecture) != 'X86')" Include="sentry-cli-Windows-x86_64.exe" FileHash="ef9c552f17fdd7d0043981aecf72906ddedee5d07d4699f8ee5a23103d6a2a05" />
130130
</ItemGroup>
131131

132132
<!-- Download the files -->

0 commit comments

Comments
 (0)