You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Check if event context matches current instance before invoking
Support both async and sync handler patterns consistently
Ensure proper async/await handling with ConfigureAwait
Diagram Walkthrough
flowchart LR
A["Event Handler Methods"] -->|"Wrap with context check"| B["Filter by e.Context == this"]
B -->|"If match"| C["Invoke User Handler"]
B -->|"If no match"| D["Skip Handler"]
C -->|"Async handlers"| E["await with ConfigureAwait"]
C -->|"Sync handlers"| F["Direct invocation"]
Generic: Robust Error Handling and Edge Case Management
Objective: Ensure comprehensive error handling that provides meaningful context and graceful degradation
Status: Context equality risk: The new event wrappers gate invocation on e.Context == this, which may perform reference equality and incorrectly skip handlers if e.Context represents the same logical context via a different instance (e.g., equality-by-Id).
Referred Code
returnBiDi.BrowsingContext.OnNavigationStartedAsync(async e =>{if(e.Context==this){awaithandler(e).ConfigureAwait(false);}},options.WithContext(this));}publicTask<Subscription>OnNavigationStartedAsync(Action<NavigationInfo>handler,ContextSubscriptionOptions?options=null){returnBiDi.BrowsingContext.OnNavigationStartedAsync(e =>{if(e.Context==this){handler(e);}},options.WithContext(this));}publicTask<Subscription>OnFragmentNavigatedAsync(Func<NavigationInfo,Task>handler,ContextSubscriptionOptions?options=null)
...(clipped 196lines)
To reduce code duplication, create two private helper methods—one for synchronous Action handlers and one for asynchronous Func<T, Task> handlers—to encapsulate the repeated context-filtering logic.
returnBiDi.BrowsingContext.OnNavigationStartedAsync(async e =>{if(e.Context==this){awaithandler(e).ConfigureAwait(false);}},options.WithContext(this));
publicTask<Subscription>OnNavigationStartedAsync(Func<NavigationInfo,Task>handler, ...){returnBiDi.BrowsingContext.OnNavigationStartedAsync(async e =>{if(e.Context==this){awaithandler(e).ConfigureAwait(false);}}, ...);}publicTask<Subscription>OnNavigationStartedAsync(Action<NavigationInfo>handler, ...){returnBiDi.BrowsingContext.OnNavigationStartedAsync(e =>{if(e.Context==this){handler(e);}}, ...);}// ... this pattern is repeated for many other event handlers.
After:
privateAction<T>WrapHandler<T>(Action<T>handler)whereT:IHasContext{return e =>{if(e.Context==this)handler(e);};}privateFunc<T,Task>WrapHandler<T>(Func<T,Task>handler)whereT:IHasContext{returnasync e =>{if(e.Context==this)awaithandler(e).ConfigureAwait(false);};}publicTask<Subscription>OnNavigationStartedAsync(Func<NavigationInfo,Task>handler, ...){returnBiDi.BrowsingContext.OnNavigationStartedAsync(WrapHandler(handler), ...);}publicTask<Subscription>OnNavigationStartedAsync(Action<NavigationInfo>handler, ...){returnBiDi.BrowsingContext.OnNavigationStartedAsync(WrapHandler(handler), ...);}// ... all other handlers are simplified similarly.
Suggestion importance[1-10]: 9
__
Why: The suggestion correctly identifies significant code duplication across all modified methods and proposes an excellent refactoring that would centralize the logic, greatly improving code quality and maintainability.
High
Possible issue
Add exception handling to handlers
Add try-catch blocks around the invocation of user-provided handler delegates in all event subscription methods. This prevents unhandled exceptions within user code from crashing the application.
Why: This suggestion correctly identifies that unhandled exceptions in user-provided event handlers can crash the application. Wrapping the handler calls in a try-catch block is a valid strategy to improve the library's robustness.
Medium
validate handler parameter
Add a null check for the handler parameter at the beginning of the method and throw an ArgumentNullException if it is null.
public Task<Subscription> OnNavigationStartedAsync(Func<NavigationInfo, Task> handler, ContextSubscriptionOptions? options = null)
{
+ if (handler is null)+ {+ throw new ArgumentNullException(nameof(handler));+ }
Apply / Chat
Suggestion importance[1-10]: 6
__
Why: This is a good practice for public APIs to validate arguments and fail early. Adding a null check for the handler parameter improves code robustness and provides clearer error messages.
Low
Learned best practice
Extract shared context-filter helper
The PR repeats the same context-filtering wrapper pattern across many event methods; extract a small private helper to centralize the filter + invocation and call it from each handler to reduce duplication and future drift.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
User description
Recently we went away from concept of
ContextEventArgs, meaning handler should be aware itself.Continuation of #16694
🔧 Implementation Notes
I use
==operator here, is it risky?🔄 Types of changes
PR Type
Bug fix
Description
Wrap event handlers with context filtering logic
Check if event context matches current instance before invoking
Support both async and sync handler patterns consistently
Ensure proper async/await handling with ConfigureAwait
Diagram Walkthrough
File Walkthrough
BrowsingContext.cs
Implement context-aware event handler filteringdotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContext.cs
if (e.Context == this)checks before invoking user handlersActionandFunchandler patternsConfigureAwait(false)to async handler invocations for properasync context