-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
.pr_agent_auto_best_practices
Pattern 1: Add null parameter validation checks at the start of methods to prevent NullReferenceExceptions, especially for required parameters marked as nullable. The validation should throw ArgumentNullException with a clear message.
Example code before:
public void ProcessData(string? input) {
var result = input.ToUpper(); // Potential NullReferenceException
}
Example code after:
public void ProcessData(string? input) {
ArgumentNullException.ThrowIfNull(input, nameof(input));
var result = input.ToUpper(); // Safe to use
}
Relevant past accepted suggestions:
Suggestion 1:
Add null parameter validation
Add null check for webDriver parameter to prevent NullReferenceException when calling the extension method with null
dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs [29-31]
public static async Task<BiDi> AsBiDiAsync(this IWebDriver webDriver)
{
+ ArgumentNullException.ThrowIfNull(webDriver);
var webSocketUrl = ((IHasCapabilities)webDriver).Capabilities.GetCapability("webSocketUrl");
Suggestion 2:
Add proper validation for nullable values before using them to prevent potential runtime errors
The code uses null-forgiving operator (!) on webSocketUrl.ToString() which could lead to runtime errors if webSocketUrl is null. Instead, validate the value before using it and provide a clear error message.
dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs [33-35]
-if (webSocketUrl is null) throw new BiDiException("The driver is not compatible with bidirectional protocol or \"webSocketUrl\" not enabled in driver options.");
-var bidi = await BiDi.ConnectAsync(webSocketUrl.ToString()!).ConfigureAwait(false);
+if (webSocketUrl is null)
+ throw new BiDiException("The driver is not compatible with bidirectional protocol or \"webSocketUrl\" not enabled in driver options.");
+var webSocketUrlStr = webSocketUrl.ToString();
+if (string.IsNullOrEmpty(webSocketUrlStr))
+ throw new BiDiException("Invalid empty webSocketUrl value");
+
+var bidi = await BiDi.ConnectAsync(webSocketUrlStr).ConfigureAwait(false);
+
Suggestion 3:
Add parameter validation to prevent null reference exceptions
Add null check for value parameter in FromJson method to prevent potential NullReferenceException when deserializing JSON.
dotnet/src/webdriver/Response.cs [74-76]
public static Response FromJson(string value)
{
+ if (string.IsNullOrEmpty(value))
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
Dictionary<string, object> rawResponse = JsonSerializer.Deserialize<Dictionary<string, object>>(value, s_jsonSerializerOptions)
Suggestion 4:
Maintain consistent null parameter validation by throwing exceptions instead of silently handling null values
The DeleteCookieNamed method should throw an ArgumentNullException when name is null, similar to how AddCookie handles null parameters. This maintains consistency in null parameter handling across the class.
dotnet/src/webdriver/CookieJar.cs [99-107]
public void DeleteCookieNamed(string? name)
{
- if (name is not null)
+ if (name is null)
{
- Dictionary<string, object> parameters = new Dictionary<string, object>();
- parameters.Add("name", name);
- this.driver.InternalExecute(DriverCommand.DeleteCookie, parameters);
+ throw new ArgumentNullException(nameof(name));
}
+ Dictionary<string, object> parameters = new Dictionary<string, object>();
+ parameters.Add("name", name);
+ this.driver.InternalExecute(DriverCommand.DeleteCookie, parameters);
}
Suggestion 5:
Add null check for required parameter to prevent runtime errors
Add null check for target parameter in ConvertElement() since it's marked as nullable but the method assumes it's non-null.
dotnet/src/webdriver/Interactions/PointerInputDevice.cs [584-588]
private Dictionary<string, object> ConvertElement()
{
+ if (this.target == null)
+ {
+ throw new ArgumentNullException(nameof(target));
+ }
if (this.target is IWebDriverObjectReference element)
{
return element.ToDictionary();
}
Suggestion 6:
Add parameter validation to prevent null reference exceptions
Add null check for key parameter in SetPreferenceValue method to prevent potential issues with null keys.
dotnet/src/webdriver/Firefox/Preferences.cs [166-168]
private void SetPreferenceValue(string key, JsonNode? value)
{
+ if (key == null)
+ throw new ArgumentNullException(nameof(key));
if (!this.IsSettablePreference(key))
Pattern 2: Replace direct null checks with null-coalescing (??) and null-conditional (?.) operators for safer and more concise null handling, especially when accessing properties or converting values to string.
Example code before:
string value = obj != null ? obj.ToString() : "";
Example code after:
string value = obj?.ToString() ?? string.Empty;
Relevant past accepted suggestions:
Suggestion 1:
Simplify null check using null-coalescing operator for better readability and maintainability
The null-coalescing operator (??) should be used instead of the pattern matching expression to check for null StreamWriter, as it's more idiomatic in C# and clearer in intent.
dotnet/src/webdriver/Internal/Logging/FileLogHandler.cs [83-91]
-if (_streamWriter is not { } writer)
-{
- throw new ObjectDisposedException(nameof(FileLogHandler));
-}
+var writer = _streamWriter ?? throw new ObjectDisposedException(nameof(FileLogHandler));
lock (_lockObj)
{
writer.WriteLine($"{logEvent.Timestamp:yyyy-MM-dd HH:mm:ss.fff} {_levels[(int)logEvent.Level]} {logEvent.IssuedBy.Name}: {logEvent.Message}");
}
Suggestion 2:
Use null-coalescing operator with null-conditional operator for safer string conversion
Consider using the null-coalescing operator (??) instead of the null-conditional operator (?.) followed by ToString(). This will provide a default empty string if the value is null, avoiding potential null reference exceptions.
dotnet/src/webdriver/ErrorResponse.cs [55]
-this.message = responseValue["message"].ToString() ?? "";
+this.message = responseValue["message"]?.ToString() ?? string.Empty;
Suggestion 3:
Use null-conditional operator for safer null checking
Use the null-forgiving operator (!) only when absolutely necessary. Consider using the null-conditional operator (?.) for a safer approach to null checking.
dotnet/src/webdriver/Alert.cs [50]
-return commandResponse.Value.ToString()!;
+return commandResponse.Value?.ToString() ?? string.Empty;
Pattern 3: Ensure proper error messages include actual values or states to help with debugging, especially in exception messages and validation errors.
Example code before:
throw new ArgumentException("Invalid configuration");
Example code after:
throw new ArgumentException($"Invalid configuration. Provided value: '{config}'");
Relevant past accepted suggestions:
Suggestion 1:
Enhance error messages with actual values for better debugging experience
Include the actual value in the exception message to help with debugging when an invalid cookie name is provided.
dotnet/src/webdriver/CookieJar.cs [82]
-throw new ArgumentException("Cookie name cannot be empty", nameof(name));
+throw new ArgumentException($"Cookie name cannot be empty. Provided value: '{name}'", nameof(name));
Suggestion 2:
Provide accurate error messages that reflect the actual system locale instead of assuming Arabic
The error message incorrectly assumes the system language is Arabic when it's any non-English locale. Update the message to be more accurate and include the actual locale in the error message.
java/src/org/openqa/selenium/chrome/ChromeDriverService.java [289]
-throw new NumberFormatException("Couldn't format the port numbers because the System Language is arabic: \"" + String.format("--port=%d", getPort()) +
+throw new NumberFormatException("Couldn't format the port numbers due to non-English system locale '" + Locale.getDefault(Locale.Category.FORMAT) + "': \"" + String.format("--port=%d", getPort()) +
Suggestion 3:
Correct the error message by removing an unnecessary character
Remove the '=' sign from the error message as it appears to be a typo and doesn't add any meaningful information.
java/src/org/openqa/selenium/manager/SeleniumManager.java [198]
-throw new WebDriverException("Linux ARM64= is not supported by Selenium Manager");
+throw new WebDriverException("Linux ARM64 is not supported by Selenium Manager");
Pattern 4: Use locale-independent number formatting when converting numbers to strings to ensure consistent behavior across different system languages and cultures.
Example code before:
args.add(String.format("--port=%d", port));
Example code after:
args.add("--port=" + String.valueOf(port));
Relevant past accepted suggestions:
Suggestion 1:
Use locale-independent number formatting to handle port numbers consistently across all system languages
Instead of checking only for non-English locale, implement proper number formatting using a Locale-independent approach. Use String.valueOf() or Integer.toString() for port number conversion to avoid locale-specific formatting issues.
java/src/org/openqa/selenium/chrome/ChromeDriverService.java [287-291]
-args.add(String.format("--port=%d", getPort()));
-if(!Locale.getDefault(Locale.Category.FORMAT).getLanguage().equals("en")) {
- throw new NumberFormatException("Couldn't format the port numbers because the System Language is arabic: \"" + String.format("--port=%d", getPort()) +
- "\", please make sure to add the required arguments \"-Duser.language=en -Duser.region=US\" to your JVM, for more info please visit :" + "\n https://www.selenium.dev/documentation/webdriver/browsers/");
-}
+args.add("--port=" + String.valueOf(getPort()));
Suggestion 2:
Ensure consistent locale-independent number formatting across all port number handling
The websocket port formatting is inconsistent with the main port handling and could face the same locale issues. Apply the same locale-independent formatting to the websocket port.
java/src/org/openqa/selenium/firefox/GeckoDriverService.java [223-230]
-args.add(String.format("--port=%d", getPort()));
-if(!Locale.getDefault(Locale.Category.FORMAT).getLanguage().equals("en")) {
- throw new NumberFormatException("Couldn't format the port numbers because the System Language is arabic: \"" + String.format("--port=%d", getPort()) +
- "\", please make sure to add the required arguments \"-Duser.language=en -Duser.region=US\" to your JVM, for more info please visit :" + "\n https://www.selenium.dev/documentation/webdriver/browsers/");
-}
+args.add("--port=" + String.valueOf(getPort()));
+int wsPort = PortProber.findFreePort();
+args.add("--websocket-port=" + String.valueOf(wsPort));
-int wsPort = PortProber.findFreePort();
-args.add(String.format("--websocket-port=%d", wsPort));
-
Pattern 5: Optimize map/dictionary operations by using a single mutable instance and conditional additions instead of creating new instances for each modification.
Example code before:
Map<String, Object> map = Map.of("key1", value1);
if (hasMore) {
map = Map.of("key1", value1, "key2", value2);
}
Example code after:
Map<String, Object> map = new HashMap<>();
map.put("key1", value1);
if (hasMore) {
map.put("key2", value2);
}
Relevant past accepted suggestions:
Suggestion 1:
Optimize map creation efficiency
The toMap() method creates new Map instances unnecessarily. Optimize by using a single mutable map and conditionally adding the contexts.
java/src/org/openqa/selenium/bidi/network/SetCacheBehaviorParameters.java [37-45]
public Map<String, Object> toMap() {
- Map<String, Object> map = Map.of("cacheBehavior", cacheBehavior.toString());
-
+ Map<String, Object> map = new HashMap<>();
+ map.put("cacheBehavior", cacheBehavior.toString());
+
if (contexts != null && !contexts.isEmpty()) {
- return Map.of("cacheBehavior", cacheBehavior.toString(), "contexts", contexts);
+ map.put("contexts", contexts);
}
-
+
return map;
}
Suggestion 2:
Maintain consistent null parameter validation by throwing exceptions instead of silently handling null values
The DeleteCookieNamed method should throw an ArgumentNullException when name is null, similar to how AddCookie handles null parameters. This maintains consistency in null parameter handling across the class.
dotnet/src/webdriver/CookieJar.cs [99-107]
public void DeleteCookieNamed(string? name)
{
- if (name is not null)
+ if (name is null)
{
- Dictionary<string, object> parameters = new Dictionary<string, object>();
- parameters.Add("name", name);
- this.driver.InternalExecute(DriverCommand.DeleteCookie, parameters);
+ throw new ArgumentNullException(nameof(name));
}
+ Dictionary<string, object> parameters = new Dictionary<string, object>();
+ parameters.Add("name", name);
+ this.driver.InternalExecute(DriverCommand.DeleteCookie, parameters);
}
[Auto-generated best practices - 2025-01-27]
This wiki is not where you want to be! Visit the Wiki Home for more useful links
Getting Involved
Build Instructions
Releasing Selenium
Updating Chromium DevTools
Ruby Development
Python Bindings
Ruby Bindings
WebDriverJs
This content is being evaluated for where it belongs
Architectural Overview
Automation Atoms
HtmlUnitDriver
Lift Style API
LoadableComponent
Logging
PageFactory
RemoteWebDriver
Xpath In WebDriver
Moved to Official Documentation
Bot Style Tests
Buck
Continuous Integration
Crazy Fun Build
Design Patterns
Desired Capabilities
Developer Tips
Domain Driven Design
Firefox Driver
Firefox Driver Internals
Focus Stealing On Linux
Frequently Asked Questions
Google Summer Of Code
Grid Platforms
History
Internet Explorer Driver
InternetExplorerDriver Internals
Next Steps
PageObjects
RemoteWebDriverServer
Roadmap
Scaling WebDriver
SeIDE Release Notes
Selenium Emulation
Selenium Grid 4
Selenium Help
Shipping Selenium 3
The Team
TLC Meetings
Untrusted SSL Certificates
WebDriver For Mobile Browsers
Writing New Drivers