Skip to content

chore: enforce -Error suffix on sendTelemetryError event names#1941

Merged
mdesmet merged 2 commits intomasterfrom
chore/lint-sendtelemetryerror-suffix
May 8, 2026
Merged

chore: enforce -Error suffix on sendTelemetryError event names#1941
mdesmet merged 2 commits intomasterfrom
chore/lint-sendtelemetryerror-suffix

Conversation

@ralphstodomingo
Copy link
Copy Markdown
Contributor

@ralphstodomingo ralphstodomingo commented May 8, 2026

Summary

Adds an ESLint rule that fails on sendTelemetryError calls whose first argument is a string literal — or a TelemetryEvents[...] enum lookup — that doesn't end in Error. Renames the four pre-existing violations so the rule lands green.

Follow-up to #1940, where @mdesmet's review surfaced unhandledRejectioncatchAllError and the broader naming convention. Without a lint rule, the next non-conforming call gets caught at review time, not dev time.

Why this convention

~30 of ~33 existing sendTelemetryError call sites already follow the -Error suffix:

installDepsError, registerDBTProjectError, sqlPreviewNotLoadingError,
compileNodePythonError, compileNodeUnknownError, validateSQLDryRunError,
catalogPythonError, catalogUnknownError, generateSchemaYMLPythonError,
extensionActivationError, ...

It makes App Insights queries trivially distinguishable between error events and event events (endsWith("Error") vs other), and is what telemetry/index.ts:37 enforces at runtime for the ${eventName}Error wrapper. The lint rule pulls the same constraint up to dev-time for direct sendTelemetryError calls.

What this PR does

1. Lint rule — .eslintrc.json

Two no-restricted-syntax selectors:

{
  "selector": "CallExpression[callee.property.name='sendTelemetryError'][arguments.0.type='Literal'][arguments.0.value!=/Error$/]",
  "message": "First argument to sendTelemetryError must be an event name ending in 'Error'..."
},
{
  "selector": "CallExpression[callee.property.name='sendTelemetryError'] > MemberExpression[object.name='TelemetryEvents'][property.value!=/Error$/]",
  "message": "TelemetryEvents key passed to sendTelemetryError must end in 'Error'..."
}

The first selector catches inline string literals. The second catches TelemetryEvents["Foo/NotError"] lookups by inspecting the MemberExpression property's literal value at lint time.

Dynamic first args are deliberately not flagged — variables (name), template literals (`${eventName}Error`), as-cast member access (params.eventName as string), etc. Their runtime value can't be validated statically; the existing rules cover the cases that ARE statically checkable, and the wrapper at telemetry/index.ts:37 (${eventName}Error) already enforces the suffix at runtime for indirect callers.

2. Renames so the rule lands green

Before After File
formatDbtModelApplyDiffFailed formatDbtModelApplyDiffError dbtDocumentFormattingEditProvider.ts:91,104
columnLevelLineageRequestTimeout columnLevelLineageRequestTimeoutError dbtLineageService.ts:487
TelemetryEvents["QueryHistory/Cleared"] TelemetryEvents["QueryHistory/ClearError"] events.ts:62, queryResultPanel.ts:415
"unhandlederror" (test fixture) "unhandledRejectionError" telemetryService.test.ts:80,86

App Insights impact

The rename changes the event name written to App Insights for these four cases. Anyone with saved queries or dashboards keying off the old names needs to update them. None of the four event names appear above the noise floor in current production cluster reports (verified via the Channel-closed triage that motivated #1940), so the rename causes a brief gap rather than a silent loss.

Test plan

  • npx eslint 'src/**/*.ts' before rename: 4 no-restricted-syntax errors flagged (the four call sites above)
  • npx eslint 'src/**/*.ts' after rename: 0 no-restricted-syntax errors. The remaining 7 errors are pre-existing prettier/prettier issues in bigQueryCostEstimate.test.ts and telemetryService.test.ts confirmed present on master — unrelated
  • grep -r 'formatDbtModelApplyDiffFailed\|columnLevelLineageRequestTimeout"\|QueryHistory/Cleared\|"unhandlederror"' src/: 0 matches — all old names replaced
  • Verified the rule fires by reverting one of the renames locally — the lint output flags it again

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Standardized error telemetry naming across the app for consistent reporting.
    • Added a new telemetry event for query history clear errors to improve visibility.
    • Updated telemetry to forward additional diagnostic fields (error name and message).
  • Tests
    • Expanded tests to verify forwarding of error name/message and corrected related test event names.

Adds two `no-restricted-syntax` rules to `.eslintrc.json` that flag any
`sendTelemetryError` call whose first argument is a string literal —
or a `TelemetryEvents[...]` enum lookup — that does not end in `Error`.
Dynamic first args (variables, computed expressions, template literals)
are deliberately left unchecked because their runtime value can't be
validated statically.

Why: ~30 of ~33 existing call sites already follow the convention
(`compileNodePythonError`, `extensionActivationError`,
`registerDBTProjectError`, ...). The convention makes App Insights
queries trivially distinguishable between event-name patterns
(`endsWith("Error")` vs other), and was reinforced by mdesmet's review
on #1940 (renamed `unhandledRejection` → `catchAllError`). Without a
lint rule, the next non-conforming call lands at review time rather
than dev time.

Renames the four pre-existing violations so the rule lands green:

- `formatDbtModelApplyDiffFailed` → `formatDbtModelApplyDiffError`
- `columnLevelLineageRequestTimeout` → `columnLevelLineageRequestTimeoutError`
- `TelemetryEvents["QueryHistory/Cleared"]` → `TelemetryEvents["QueryHistory/ClearError"]`
- `"unhandlederror"` (test fixture) → `"unhandledRejectionError"`

App Insights impact: dashboards or saved queries keying off the
old event names need to be updated. None of the four event names show
up in production cluster reports above the noise floor; the rename
will cause a brief gap rather than a silent loss.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 90cc96bf-23d6-4e96-9c1f-ab48c7271ffb

📥 Commits

Reviewing files that changed from the base of the PR and between f7be110 and 450b764.

📒 Files selected for processing (1)
  • .eslintrc.json
✅ Files skipped from review due to trivial changes (1)
  • .eslintrc.json

Walkthrough

Enforces a telemetry naming convention requiring error event names to end with "Error": adds ESLint rules, adds QueryHistory/ClearError to TelemetryEvents, renames three emitted error event keys, and updates tests to validate forwarding of error.name and error.message.

Changes

Telemetry Naming Convention Enforcement

Layer / File(s) Summary
ESLint Rule Configuration
.eslintrc.json
no-restricted-syntax rules enforce sendTelemetryError calls to pass event names (string literals or TelemetryEvents enum keys) ending with Error.
Telemetry Event Definition
src/telemetry/events.ts
New QueryHistory/ClearError enum member added to TelemetryEvents in the QueryHistory section.
Telemetry Event Usage Updates
src/document_formatting_edit_provider/dbtDocumentFormattingEditProvider.ts, src/services/dbtLineageService.ts, src/webview_provider/queryResultPanel.ts
Error event names are renamed: formatDbtModelApplyDiffFailedformatDbtModelApplyDiffError, columnLevelLineageRequestTimeoutcolumnLevelLineageRequestTimeoutError, and QueryHistory/ClearedQueryHistory/ClearError.
Telemetry Service Tests
src/test/suite/telemetryService.test.ts
Test coverage verifies sendTelemetryError forwards error.name as error_name and error.message as error_message alongside existing error.code and stack properties.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • mdesmet
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding an ESLint rule to enforce the -Error suffix on sendTelemetryError event names.
Description check ✅ Passed The description is comprehensive and well-structured, covering the problem, solution, rationale, and testing approach, though it deviates from the provided template format.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/lint-sendtelemetryerror-suffix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

Bundle Size Report

darwin-arm64: 74.2 MB
Category Size Compressed Files
Webview JS bundles 36.3 MB 12.3 MB 346
Native: altimate-core 35.1 MB 14.0 MB 1
Media assets 29.6 MB 25.8 MB 91
Native: zeromq 20.5 MB 8.2 MB 15
Webview images 15.3 MB 12.2 MB 18
Extension backend (JS) 2.7 MB 0.6 MB 1
Python packages 2.0 MB 0.5 MB 95
Native: other node_modules 1.0 MB 0.2 MB 139
Webview CSS 0.8 MB 0.1 MB 2
Webview other 0.5 MB 0.1 MB 5
Other 0.1 MB 26 KB 15
Total 143.9 MB 74.0 MB 728
linux-x64: 75.9 MB
Category Size Compressed Files
Native: altimate-core 41.8 MB 15.1 MB 1
Webview JS bundles 36.3 MB 12.3 MB 346
Media assets 29.6 MB 25.8 MB 91
Native: zeromq 21.9 MB 8.7 MB 16
Webview images 15.3 MB 12.2 MB 18
Extension backend (JS) 2.7 MB 0.6 MB 1
Python packages 2.0 MB 0.5 MB 95
Native: other node_modules 1.0 MB 0.2 MB 139
Webview CSS 0.8 MB 0.1 MB 2
Webview other 0.5 MB 0.1 MB 5
Other 0.1 MB 26 KB 15
Total 152.0 MB 75.7 MB 729
win32-x64: 76.8 MB
Category Size Compressed Files
Native: altimate-core 50.3 MB 16.2 MB 1
Webview JS bundles 36.3 MB 12.3 MB 346
Media assets 29.6 MB 25.8 MB 91
Native: zeromq 20.0 MB 8.1 MB 15
Webview images 15.3 MB 12.2 MB 18
Extension backend (JS) 2.7 MB 0.6 MB 1
Native: other node_modules 2.3 MB 0.7 MB 147
Python packages 2.0 MB 0.5 MB 95
Webview CSS 0.8 MB 0.1 MB 2
Webview other 0.5 MB 0.1 MB 5
Other 0.1 MB 26 KB 15
Total 159.8 MB 76.7 MB 736

@ralphstodomingo ralphstodomingo self-assigned this May 8, 2026
@ralphstodomingo ralphstodomingo requested a review from mdesmet May 8, 2026 08:20
@ralphstodomingo ralphstodomingo marked this pull request as ready for review May 8, 2026 08:20
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.eslintrc.json:
- Around line 28-29: Update the ESLint rule selector that targets
sendTelemetryError usages so it explicitly matches the first argument access on
TelemetryEvents; replace the current selector string (which uses the child
combinator and MemberExpression) with one that constrains to
CallExpression[callee.property.name='sendTelemetryError'] >
MemberExpression[object.name='TelemetryEvents'] that is specifically at
arguments.0 (i.e., use a path like
CallExpression[callee.property.name='sendTelemetryError'] >
:matches(MemberExpression)[arguments.0.type] or an equivalent AST selector that
targets arguments.0) so only the first parameter is validated; keep references
to sendTelemetryError and TelemetryEvents to locate the rule in .eslintrc.json
and ensure the message remains unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 34456460-6320-4588-9547-7f88fdb8c82d

📥 Commits

Reviewing files that changed from the base of the PR and between 68ef665 and f7be110.

📒 Files selected for processing (6)
  • .eslintrc.json
  • src/document_formatting_edit_provider/dbtDocumentFormattingEditProvider.ts
  • src/services/dbtLineageService.ts
  • src/telemetry/events.ts
  • src/test/suite/telemetryService.test.ts
  • src/webview_provider/queryResultPanel.ts

Comment thread .eslintrc.json Outdated
Address @coderabbitai review on PR #1941. Previous form used a `>`
combinator which matches any direct `MemberExpression` child of the
`CallExpression` whose `object.name='TelemetryEvents'`. In practice
this only matches the first argument (since the second arg is the
error object, not a TelemetryEvents lookup), but the explicit
`[arguments.0.object.name=...][arguments.0.property.value!=...]`
form is tighter and removes any chance of false positives if a
caller ever passes `TelemetryEvents[...]` in a later position.

Verified by temporarily reverting the `QueryHistory/ClearError`
rename and confirming the new selector still fires.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dev-punia-altimate
Copy link
Copy Markdown
Contributor

✅ Tests — All Passed

cc @ralphstodomingo

@mdesmet mdesmet merged commit 0a044e1 into master May 8, 2026
21 checks passed
@mdesmet mdesmet deleted the chore/lint-sendtelemetryerror-suffix branch May 8, 2026 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants