[dotnet] [bidi] Null guard for event handlers by nvborisenko · Pull Request #16967 · SeleniumHQ/selenium
PR Code Suggestions ✨
Explore these optional code suggestions:
| Category | Suggestion | Impact |
| High-level |
Refactor to avoid massive duplicationThe PR adds many nearly identical private handler methods, causing significant Examples:dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContext.cs [309-467]private async Task HandleNavigationStartedAsync(NavigationInfo e, Func<NavigationInfo, Task> handler) { if (Equals(e.Context)) { await handler(e).ConfigureAwait(false); } } private void HandleNavigationStarted(NavigationInfo e, Action<NavigationInfo> handler) { ... (clipped 149 lines) dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextNetworkModule.cs [183-261]private async Task HandleBeforeRequestSentAsync(BeforeRequestSentEventArgs e, Func<BeforeRequestSentEventArgs, Task> handler) { if (context.Equals(e.Context)) { await handler(e).ConfigureAwait(false); } } private void HandleBeforeRequestSent(BeforeRequestSentEventArgs e, Action<BeforeRequestSentEventArgs> handler) { ... (clipped 69 lines) Solution Walkthrough:Before:// In dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContext.cs public Task<Subscription> OnNavigationStartedAsync(Action<NavigationInfo> handler, ...) { if (handler is null) throw new ArgumentNullException(nameof(handler)); return BiDi.BrowsingContext.OnNavigationStartedAsync( e => HandleNavigationStarted(e, handler), ...); } private void HandleNavigationStarted(NavigationInfo e, Action<NavigationInfo> handler) { if (Equals(e.Context)) { handler(e); } } // ... dozens of similar handler methods for different events ... private void HandleFragmentNavigated(NavigationInfo e, Action<NavigationInfo> handler) { if (Equals(e.Context)) { handler(e); } } After:// In a new helper class or within each module private static Action<T> CreateContextFilteredHandler<T>( T e, Action<T> handler, BrowsingContext context) where T : IContextEventArgs { return (args) => { if (context.Equals(args.Context)) { handler(args); } }; } // In dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContext.cs public Task<Subscription> OnNavigationStartedAsync(Action<NavigationInfo> handler, ...) { if (handler is null) throw new ArgumentNullException(nameof(handler)); return BiDi.BrowsingContext.OnNavigationStartedAsync( CreateContextFilteredHandler(handler, this), ...); } Suggestion importance[1-10]: 9__ Why: The suggestion correctly identifies massive code duplication introduced across multiple files, which contradicts the PR's goal of improving maintainability and is a significant design flaw. | High |
| Possible issue |
Restore special handling for subscription optionsRestore the special handling for dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextLogModule.cs [28-44] public Task<Subscription> OnEntryAddedAsync(Func<Log.LogEntry, Task> handler, ContextSubscriptionOptions? options = null)
{
if (handler is null) throw new ArgumentNullException(nameof(handler));
return logModule.OnEntryAddedAsync(
e => HandleEntryAddedAsync(e, handler),
- ContextSubscriptionOptions.WithContext(options, context));
+ new SubscriptionOptions() { Timeout = options?.Timeout }); // special case, don't scope to context, awaiting https://github.com/w3c/webdriver-bidi/issues/1032
}
public Task<Subscription> OnEntryAddedAsync(Action<Log.LogEntry> handler, ContextSubscriptionOptions? options = null)
{
if (handler is null) throw new ArgumentNullException(nameof(handler));
return logModule.OnEntryAddedAsync(
e => HandleEntryAdded(e, handler),
- ContextSubscriptionOptions.WithContext(options, context));
+ new SubscriptionOptions() { Timeout = options?.Timeout }); // special case, don't scope to context, awaiting https://github.com/w3c/webdriver-bidi/issues/1032
}
Suggestion importance[1-10]: 8__ Why: The suggestion correctly identifies that the refactoring removed special-case logic for | Medium |
| General |
Guard against null type infoAdd a null check for the dotnet/src/webdriver/BiDi/Broker.cs [165] +if (jsonTypeInfo is null) + throw new ArgumentNullException(nameof(jsonTypeInfo), "Event JSON type info cannot be null."); _eventTypesMap[eventName] = jsonTypeInfo;
Suggestion importance[1-10]: 7__ Why: The suggestion correctly points out a missing null check for the | Medium |
| Learned best practice |
Centralize repeated handler logicReplace the many per-event dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContext.cs [309-339] -private async Task HandleNavigationStartedAsync(NavigationInfo e, Func<NavigationInfo, Task> handler) +private Task InvokeIfThisContextAsync<T>(T e, Func<T, Task> handler, Func<T, BrowsingContext> getContext) { - if (Equals(e.Context)) - { - await handler(e).ConfigureAwait(false); - } + return Equals(getContext(e)) ? handler(e) : Task.CompletedTask; } -private void HandleNavigationStarted(NavigationInfo e, Action<NavigationInfo> handler) +private void InvokeIfThisContext<T>(T e, Action<T> handler, Func<T, BrowsingContext> getContext) { - if (Equals(e.Context)) + if (Equals(getContext(e))) { handler(e); } } -private async Task HandleFragmentNavigatedAsync(NavigationInfo e, Func<NavigationInfo, Task> handler) -{ - if (Equals(e.Context)) - { - await handler(e).ConfigureAwait(false); - } -} +private Task HandleNavigationStartedAsync(NavigationInfo e, Func<NavigationInfo, Task> handler) => + InvokeIfThisContextAsync(e, handler, x => x.Context); -private void HandleFragmentNavigated(NavigationInfo e, Action<NavigationInfo> handler) -{ - if (Equals(e.Context)) - { - handler(e); - } -} +private void HandleNavigationStarted(NavigationInfo e, Action<NavigationInfo> handler) => + InvokeIfThisContext(e, handler, x => x.Context); +private Task HandleFragmentNavigatedAsync(NavigationInfo e, Func<NavigationInfo, Task> handler) => + InvokeIfThisContextAsync(e, handler, x => x.Context); + +private void HandleFragmentNavigated(NavigationInfo e, Action<NavigationInfo> handler) => + InvokeIfThisContext(e, handler, x => x.Context); +
Suggestion importance[1-10]: 6__ Why: | Low |
| ||