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;