Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Boilerplate exception handling (#9635) #9636

Merged
merged 2 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,6 @@ private void HandleException(Exception exp,
}
parameters["ComponentType"] = GetType().FullName;

ExceptionHandler.Handle(exp, displayKind: ExceptionDisplayKind.Interrupting, parameters, lineNumber, memberName, filePath);
ExceptionHandler.Handle(exp, ExceptionDisplayKind.Default, parameters, lineNumber, memberName, filePath);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,11 @@ public static IServiceCollection AddClientCoreProjectServices(this IServiceColle
if (string.IsNullOrEmpty(accessToken) is false &&
IAuthTokenProvider.ParseAccessToken(accessToken, validateExpiry: true).IsAuthenticated() is false)
{
return await authManager.RefreshToken(requestedBy: nameof(HubConnectionBuilder));
try
{
return await authManager.RefreshToken(requestedBy: nameof(HubConnectionBuilder));
}
catch (ServerConnectionException) { /* If client gets disconnected and access token become expired, then this code will be called every few seconds and will show annoying error to the user. */ }
}

return accessToken;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ async Task RefreshTokenImplementation()
{
{ "AdditionalData", "Refreshing access token failed." },
{ "RefreshTokenRequestedBy", requestedBy }
}, displayKind: exp is ReusedRefreshTokenException ? ExceptionDisplayKind.NonInterrupting : ExceptionDisplayKind.Interrupting);
});

if (exp is UnauthorizedException // refresh token is also invalid.
|| exp is ReusedRefreshTokenException && refreshToken == await storageService.GetItem("refresh_token"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public abstract partial class ClientExceptionHandlerBase : SharedExceptionHandle
[AutoInject] protected readonly ILogger<ClientExceptionHandlerBase> Logger = default!;

public void Handle(Exception exception,
ExceptionDisplayKind displayKind = ExceptionDisplayKind.Interrupting,
ExceptionDisplayKind displayKind = ExceptionDisplayKind.Default,
Dictionary<string, object?>? parameters = null,
[CallerLineNumber] int lineNumber = 0,
[CallerMemberName] string memberName = "",
Expand Down Expand Up @@ -50,6 +50,11 @@ protected virtual void Handle(Exception exception,

string exceptionMessageToShow = GetExceptionMessageToShow(exception);

if (displayKind is ExceptionDisplayKind.Default)
{
displayKind = GetDisplayKind(exception);
}

if (displayKind is ExceptionDisplayKind.NonInterrupting)
{
SnackBarService.Error("Boilerplate", exceptionMessageToShow);
Expand All @@ -63,4 +68,12 @@ protected virtual void Handle(Exception exception,
Debugger.Break();
}
}

private ExceptionDisplayKind GetDisplayKind(Exception exception)
{
if (exception is ServerConnectionException or ReusedRefreshTokenException)
return ExceptionDisplayKind.NonInterrupting;

return ExceptionDisplayKind.Interrupting;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ public enum ExceptionDisplayKind
/// <summary>
/// Shows an auto-dismissed message (e.g., a toast notification)
/// </summary>
NonInterrupting
NonInterrupting,
/// <summary>
/// Exception display kind gets chosen by exception type automatically.
/// </summary>
Default
}

public interface IExceptionHandler
{
void Handle(Exception exception,
ExceptionDisplayKind displayKind = ExceptionDisplayKind.Interrupting,
ExceptionDisplayKind displayKind = ExceptionDisplayKind.Default,
Dictionary<string, object?>? parameters = null,
[CallerLineNumber] int lineNumber = 0,
[CallerMemberName] string memberName = "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,10 @@ response.IsSuccessStatusCode is false &&

return response;
}
catch (Exception exp) when ((exp is HttpRequestException && serverCommunicationSuccess is false)
|| exp is TaskCanceledException tcExp && tcExp.InnerException is TimeoutException
|| exp is HttpRequestException { StatusCode: HttpStatusCode.BadGateway or HttpStatusCode.GatewayTimeout or HttpStatusCode.ServiceUnavailable })
catch (Exception exp) when (
(exp is HttpRequestException && serverCommunicationSuccess is false)
|| (exp is TaskCanceledException tcExp && tcExp.InnerException is TimeoutException)
|| (exp is HttpRequestException { StatusCode: HttpStatusCode.BadGateway or HttpStatusCode.GatewayTimeout or HttpStatusCode.ServiceUnavailable }))
{
serverCommunicationSuccess = false; // Let's treat the server communication as failed if an exception is caught here.
throw new ServerConnectionException(localizer[nameof(AppStrings.ServerConnectionException)], exp);
Expand Down
Loading