From 8bb885a0dca60753b333f4c259a3af66f9f7bb4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 9 Dec 2025 09:54:46 +0100 Subject: [PATCH] Filter out more exceptions from being sent to sentry More or less covers the first page of client sentry issues sorted by volume, all of which is pretty much useless for anything because it's client-specific-failure noise. --- osu.Game/Online/API/APIAccess.cs | 2 +- osu.Game/Utils/SentryLogger.cs | 40 ++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 6694003b31..6fc897a8ff 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -603,7 +603,7 @@ namespace osu.Game.Online.API cancellationToken.Cancel(); } - private class WebRequestFlushedException : Exception + internal class WebRequestFlushedException : Exception { public WebRequestFlushedException(APIState state) : base($@"Request failed from flush operation (state {state})") diff --git a/osu.Game/Utils/SentryLogger.cs b/osu.Game/Utils/SentryLogger.cs index 4f916f810e..aa1fd429a7 100644 --- a/osu.Game/Utils/SentryLogger.cs +++ b/osu.Game/Utils/SentryLogger.cs @@ -2,10 +2,14 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; +using System.Net.Sockets; +using System.Net.WebSockets; +using System.Threading.Tasks; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -17,6 +21,7 @@ using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Database; using osu.Game.Models; +using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Rulesets; @@ -220,20 +225,35 @@ namespace osu.Game.Utils } } + private static readonly HashSet ignored_io_exception_hresults = + [ + // see https://stackoverflow.com/a/9294382 for how these are synthesised + unchecked((int)0x80070020), // ERROR_SHARING_VIOLATION + unchecked((int)0x80070027), // ERROR_HANDLE_DISK_FULL + unchecked((int)0x80070070), // ERROR_DISK_FULL + ]; + private bool shouldSubmitException(Exception exception) { switch (exception) { - case IOException ioe: - // disk full exceptions, see https://stackoverflow.com/a/9294382 - const int hr_error_handle_disk_full = unchecked((int)0x80070027); - const int hr_error_disk_full = unchecked((int)0x80070070); + // disk I/O failures, invalid formats, etc. - if (ioe.HResult == hr_error_handle_disk_full || ioe.HResult == hr_error_disk_full) + case IOException ioe: + if (ignored_io_exception_hresults.Contains(ioe.HResult)) return false; break; + case UnauthorizedAccessException: + case SharpCompress.Common.InvalidFormatException: + return false; + + // connectivity failures + + case TimeoutException te: + return !te.Message.Contains(@"elapsed without receiving a message from the server"); + case WebException we: switch (we.Status) { @@ -243,6 +263,16 @@ namespace osu.Game.Utils } break; + + case WebSocketException: + case SocketException: + return false; + + // stuff that should really never make it to sentry + + case APIAccess.WebRequestFlushedException: + case TaskCanceledException: + return false; } return true;