Skip to content

API Review: Diagnostic Monitor API#5565

Open
chetanpandey1266 wants to merge 1 commit intouser/chetanpandey/DiagnosticMonitorAPIfrom
user/chetanpandey/DiagnosticMonitorAPI-draft
Open

API Review: Diagnostic Monitor API#5565
chetanpandey1266 wants to merge 1 commit intouser/chetanpandey/DiagnosticMonitorAPIfrom
user/chetanpandey/DiagnosticMonitorAPI-draft

Conversation

@chetanpandey1266
Copy link
Copy Markdown
Contributor

Add Diagnostic Monitor API spec — Introduces ICoreWebView2DiagnosticMonitor, a new observation-only API that
delivers diagnostic signals (e.g., network failures) from all WebViews, profiles, and the environment through a
single DiagnosticReceived event. Host apps create a monitor via CreateDiagnosticMonitor and opt in per category
using AddDiagnosticReceivedFilter.

@chetanpandey1266 chetanpandey1266 added the API Proposal Review WebView2 API Proposal for review. label Apr 15, 2026
Copy link
Copy Markdown

@shrinaths shrinaths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prose, Grammar, and Voice Review

Line-by-line pass focused on grammar, tone, and narrative voice consistency. Suggested corrections are inline below. The overall prose quality is good — these are polish items to bring the spec to Microsoft documentation standard.

Comment on lines +8 to +11
instances and profiles within an environment. Existing APIs such as
`ServerCertificateErrorDetected` are per-WebView or per-profile,
interactive (they expect a response), and each has its own event
shape.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prose: Broken parallelism + verify API name

The subject shifts from “APIs” (plural) to “each” mid-list, breaking parallel structure. Also, please verify ServerCertificateErrorDetected is the exact API name — it may be ServerCertificateErrorReceived in the current SDK.

Suggested correction:

instances and profiles within an environment. Existing APIs such as
`ServerCertificateErrorDetected` are per-WebView or per-profile
and interactive (they expect a response); each has its own event
shape.

Comment on lines +13 to +17
The Diagnostic Monitor API introduces an observation-only monitor
object that delivers diagnostic signals from all layers — WebView,
Profile, and Environment — through a single `DiagnosticReceived`
event. Host apps create a monitor from the environment and opt in
per category using `AddDiagnosticReceivedFilter`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prose: Person shift (3rd person here vs 2nd person in Description)

This paragraph uses third person (“Host apps create a monitor”) but the Description section that follows switches to second person (“You create...”). Pick one voice consistently. Microsoft docs standard is 2nd person for narrative.

Suggested correction:

The Diagnostic Monitor API introduces an observation-only monitor
object that delivers diagnostic signals from all layers — WebView,
Profile, and Environment — through a single DiagnosticReceived
event. You create a monitor from the environment and opt in per
category using AddDiagnosticReceivedFilter.

Comment on lines +32 to +36
JSON details to your telemetry backend.
* **Targeted monitoring** — filter to specific error codes, HTTP
methods, or profile names using the JSON filter.
* **Multiple consumers** — create separate monitors for telemetry
and a debug panel, each with independent filters.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prose: Capitalize first word after em dash

Per Microsoft style guidelines, capitalize the first word after the em dash since these are standalone imperative sentences.

Suggested correction:

* **Telemetry** — Subscribe to all network errors and forward the
  JSON details to your telemetry backend.
* **Targeted monitoring** — Filter to specific error codes, HTTP
  methods, or profile names using the JSON filter.
* **Multiple consumers** — Create separate monitors for telemetry
  and a debug panel, each with independent filters.

Comment on lines +201 to +203
restrict which events are delivered. An empty JSON `"{}"` receives
all events in that category. A non-empty JSON applies field-level
matching. Calling the method again for the same category replaces
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prose: “JSON” is not a countable noun

“An empty JSON” and “A non-empty JSON” are grammatically incorrect. JSON is a format/notation, not a countable object.

Suggested correction:

You can pass a JSON object to AddDiagnosticReceivedFilter to
restrict which events are delivered. An empty JSON object ("{}") matches
all events in that category. A non-empty JSON object applies field-level

Comment on lines +273 to +276
/// errors, TLS handshake failures, connection timeouts,
/// HTTP error status codes (4xx/5xx), CORS violations,
/// and mixed-content blocks.
COREWEBVIEW2_DIAGNOSTIC_CATEGORY_NETWORK_ERROR,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prose: “mixed-content blocks” is ambiguous

“blocks” could mean “blocked requests” or “content blocks.”

Suggested correction:

  /// Network request failure including DNS resolution
  /// errors, TLS handshake failures, connection timeouts,
  /// HTTP error status codes (4xx/5xx), CORS violations,
  /// and mixed-content blocked requests.

Comment on lines +413 to +414
/// matches **any** value in each specified field
/// (OR within a field, AND across fields). String
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prose: Markdown bold will not render in IDL comments

**any** uses markdown bold syntax, but IDL /// comments are plain text — the asterisks will render as literal **any** in generated docs.

Suggested correction:

  /// matches any value in each specified field
  /// (OR within a field, AND across fields). String

Comment on lines +422 to +423
/// On failure the filter state is unchanged.
HRESULT AddDiagnosticReceivedFilter(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prose: Missing comma after introductory phrase

Suggested correction:

  /// Returns E_INVALIDARG if the JSON is malformed.
  /// On failure, the filter state is unchanged.

Comment on lines +437 to +441
/// The handler is invoked on the thread that created
/// the environment every time a diagnostic signal
/// passes a filter added with
/// `AddDiagnosticReceivedFilter`.
///
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prose: Run-on sentence — hard to parse

“the environment every time” reads as a run-on because the reader cannot tell where “environment” ends and “every time” begins.

Suggested correction:

  /// Subscribes to diagnostic events on this monitor.
  /// The handler is invoked on the thread that created
  /// the environment. It fires every time a diagnostic
  /// signal passes a filter added with
  /// AddDiagnosticReceivedFilter.

Comment on lines +459 to +462
/// receives diagnostic signals from all layers —
/// WebView, Profile, and Environment — that match its
/// filters.
///
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prose: Repetitive phrasing + missing comma

The phrase “all layers — WebView, Profile, and Environment —” appears 4+ times in the spec. After the first use in Background, subsequent uses can simply say “all layers.” Also, line 469 needs a comma before “but.”

Suggested correction for lines 459-462:

  /// Creates a new diagnostic monitor. The monitor
  /// receives diagnostic signals from all layers that
  /// match its filters.
  ///

And for line 469:

  /// The monitor is active immediately, but no events

WebView = 0,

/// Signal from a profile / NetworkContext.
Profile = 1,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prose: “NetworkContext” — is this a real type?

If NetworkContext is a real WebView2 type, format it as a code reference (backtick it). If it is a general concept, use lowercase.

Suggested correction (if not a type):

        /// Signal from a profile or its network context.

Copy link
Copy Markdown

@shrinaths shrinaths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Sample Issue: The destructor calls m_monitor.Reset() without first calling remove_DiagnosticReceived. This teaches an anti-pattern — callbacks may fire during or after destruction. Best-practice samples should demonstrate proper cleanup order.

Suggested correction:

DiagnosticComponent::~DiagnosticComponent()
{
    if (m_monitor)
    {
        // Unsubscribe before releasing the monitor to
        // ensure no callbacks arrive during teardown.
        m_monitor->remove_DiagnosticReceived(
            m_diagnosticToken);
        m_monitor.Reset();
    }
}

// events and clears filters.
m_monitor.Reset();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Sample Issue: The destructor calls m_monitor.Reset() without first calling remove_DiagnosticReceived. This teaches an anti-pattern — callbacks may fire during or after destruction. Best-practice samples should demonstrate proper cleanup order.

Suggested correction:

DiagnosticComponent::~DiagnosticComponent()
{
    if (m_monitor)
    {
        // Unsubscribe before releasing the monitor to
        // ensure no callbacks arrive during teardown.
        m_monitor->remove_DiagnosticReceived(
            m_diagnosticToken);
        m_monitor.Reset();
    }
}

Copy link
Copy Markdown

@shrinaths shrinaths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see inline


## Filter with field-level JSON criteria

You can pass a JSON object to `AddDiagnosticReceivedFilter` to
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Sample Issue: Dispose() calls _monitor?.Dispose() without first unsubscribing from DiagnosticReceived. This can cause callbacks on a disposed object.

Suggested correction:

public void Dispose()
{
    if (_monitor != null)
    {
        // Unsubscribe before disposing the monitor.
        _monitor.DiagnosticReceived -=
            OnDiagnosticReceived;
        _monitor.Dispose();
        _monitor = null;
    }
}

Copy link
Copy Markdown

@shrinaths shrinaths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see inline


private void OnDiagnosticReceived(
CoreWebView2DiagnosticMonitor sender,
CoreWebView2DiagnosticEventArgs args)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Sample Issue: The handler uses CoreWebView2DiagnosticMonitor sender — but existing WebView2 .NET events use object sender per .NET convention. If using TypedEventHandler<TSender, TArgs> (WinRT), the strong-typed sender is correct, but please verify this matches the actual projection and clarify in the spec which projection (WinRT vs .NET SDK) is being shown.

Suggested correction (if .NET SDK):

private void OnDiagnosticReceived(
    object sender,
    CoreWebView2DiagnosticEventArgs args)

Copy link
Copy Markdown

@shrinaths shrinaths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see inline

_monitor.AddDiagnosticReceivedFilter(
CoreWebView2DiagnosticCategory.NetworkError,
@"{
""profileName"": ""Default"",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Sample Issue: This sample references _environment but the class never declares this field. Either show a full class with the field declaration, or add the declaration before the method.

Suggested correction:

private CoreWebView2Environment _environment;

private void SetupFilteredDiagnostics()
{
    _monitor = _environment.CreateDiagnosticMonitor();

Copy link
Copy Markdown

@shrinaths shrinaths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see inline

}
```

### .NET C#
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Sample Issue: The error codes -105 and -7 are opaque — a developer copying this code has no idea what they mean. Name them in the comment, and consider adding a link to the Chromium net_error_list.h reference in an API Notes section.

Suggested correction:

// Only receive DNS (ERR_NAME_NOT_RESOLVED, -105)
// and timeout (ERR_TIMED_OUT, -7) errors
// for GET/POST requests from the `Default` profile.

Copy link
Copy Markdown

@shrinaths shrinaths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see inline

[propget] HRESULT Category(
[out, retval]
COREWEBVIEW2_DIAGNOSTIC_CATEGORY* value);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDL Issue: [v1_enum] is a classic COM IDL attribute. If this spec is authored in MIDL3, all enums are 32-bit by default and [v1_enum] is unnecessary. Please verify whether this attribute is still required in your toolchain — if not, remove both instances (here and line 318) to keep the IDL clean.

If this section is intentionally showing the generated classic COM IDL (for Win32 C++ consumers), then keeping [v1_enum] is correct, but consider labeling the section to clarify which IDL dialect is being shown.

/// events but should not convert it to wall-clock time.
[propget] HRESULT Timestamp(
[out, retval] INT64* value);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDL Naming Issue: The SOURCE_SCOPE compound is unusual in the WebView2 enum vocabulary. The SOURCE qualifier adds no value. Consider simplifying to COREWEBVIEW2_DIAGNOSTIC_SCOPE (and CoreWebView2DiagnosticScope in .NET/WinRT). Rename: COREWEBVIEW2_DIAGNOSTIC_SCOPE, COREWEBVIEW2_DIAGNOSTIC_SCOPE_WEB_VIEW, COREWEBVIEW2_DIAGNOSTIC_SCOPE_PROFILE, COREWEBVIEW2_DIAGNOSTIC_SCOPE_ENVIRONMENT.

/// "uri": "https://www.contoso.com/api/data"
/// }
/// ```
///
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDL Naming Issue: WebView2 convention names event args after the event: DiagnosticReceived -> ICoreWebView2DiagnosticReceivedEventArgs. The current name ICoreWebView2DiagnosticEventArgs breaks this pattern (cf. ServerCertificateErrorDetectedEventArgs). Rename to ICoreWebView2DiagnosticReceivedEventArgs (COM) / CoreWebView2DiagnosticReceivedEventArgs (.NET) throughout the spec.

/// events and clears all filters.
[uuid(E4F5A6B7-C8D9-0123-ABCD-456789012345),
object, pointer_default(unique)]
interface ICoreWebView2DiagnosticMonitor : IUnknown {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDL API Shape Issue (Blocking): The category parameter is redundant -- args.Category already exposes it. Returning {} for a mismatched category silently hides bugs. Either (a) remove the parameter entirely and rename to GetDetailsAsJson(), or (b) return E_INVALIDARG on mismatch instead of silent empty JSON. Option (a) is recommended as it eliminates the mismatch class entirely. Suggested correction: HRESULT GetDetailsAsJson([out, retval] LPWSTR* value); and correspondingly in .NET: String GetDetailsAsJson();


/// Subscribes to diagnostic events on this monitor.
/// The handler is invoked on the thread that created
/// the environment every time a diagnostic signal
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDL Naming Issue: The spec says 'Calling this method again for the same category replaces the previous filter.' This is replace/set semantics, but the Add prefix implies accumulation (like add_DiagnosticReceived which truly accumulates handlers). This will confuse developers. Suggest renaming to SetDiagnosticFilter / RemoveDiagnosticFilter -- shorter, clearer, and accurately conveys replace semantics.

/// `protocol` is the protocol scheme (e.g. "https").
/// `uri` is the request URI.
///
/// For categories the runtime does not yet populate,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking API Issue: Scope tells the kind of source (WebView/Profile/Environment) but not which instance produced the event. The filter supports profileName but the returned details JSON does not include it -- so you can filter by profile but cannot attribute received events to a profile. Add ProfileName and WebViewId properties to the event args: [propget] HRESULT ProfileName([out, retval] LPWSTR* value); [propget] HRESULT WebViewId([out, retval] LPWSTR* value); ProfileName should return empty string when Scope is Environment. WebViewId should return empty string when Scope is not WebView.

/// On failure the filter state is unchanged.
HRESULT AddDiagnosticReceivedFilter(
[in] COREWEBVIEW2_DIAGNOSTIC_CATEGORY category,
[in] LPCWSTR jsonFilter);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking API Issue: The spec only states events are raised on the environment-creating thread. It does not specify whether CreateDiagnosticMonitor, Add/RemoveDiagnosticReceivedFilter, and remove_DiagnosticReceived must also be called on that thread/apartment. Add explicit STA affinity documentation to the interface comment, e.g.: 'All members of this interface must be called on the same thread that created the ICoreWebView2Environment. Calling from a different thread returns RPC_E_WRONG_THREAD. Handlers must not block this thread.' This is consistent with other WebView2 APIs.

eventHandler,
[out] EventRegistrationToken* token);

/// Removes a handler previously added with
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDL Consistency Issue: The filter JSON uses field name uriPattern but the details JSON (line 377) returns uri. This naming inconsistency will confuse developers who naturally expect to filter on the same field name that appears in the event data. Suggest unifying to uri everywhere -- the fact that wildcards are supported in the filter value is already documented in the matching rules and does not need to be encoded in the field name.

/// `ICoreWebView2DiagnosticMonitor`. Each instance
/// represents a single diagnostic signal.
[uuid(A1B2C3D4-E5F6-7890-ABCD-EF1234567890),
object, pointer_default(unique)]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Convention Issue: Existing WebView2 specs use the header '## Win32 C++' (not '## COM'). Similarly, '### .NET C#' in the Examples section (line 161) should be '### .NET, WinRT' to match the established WebView2 spec conventions (cf. BrowserProcessExited.md, ClearBrowsingData.md).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API Proposal Review WebView2 API Proposal for review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants