Skip to content

Commit 52dbb37

Browse files
committed
Suppress missing Ruby version errors from extension telemetry
Introduce NonReportableError base class that MissingRubyError and UntrustedWorkspaceError both extend. The telemetry check in ruby.ts now uses a single instanceof NonReportableError guard, making it extensible without modifying the check for each new error type.
1 parent 46e55e4 commit 52dbb37

File tree

6 files changed

+30
-10
lines changed

6 files changed

+30
-10
lines changed

vscode/src/ruby.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import * as vscode from "vscode";
55

66
import { asyncExec, RubyInterface } from "./common";
77
import { WorkspaceChannel } from "./workspaceChannel";
8-
import { Shadowenv, UntrustedWorkspaceError } from "./ruby/shadowenv";
8+
import { Shadowenv } from "./ruby/shadowenv";
99
import { Chruby } from "./ruby/chruby";
10-
import { VersionManager } from "./ruby/versionManager";
10+
import { NonReportableError, VersionManager } from "./ruby/versionManager";
1111
import { Mise } from "./ruby/mise";
1212
import { RubyInstaller } from "./ruby/rubyInstaller";
1313
import { Rbenv } from "./ruby/rbenv";
@@ -151,7 +151,7 @@ export class Ruby implements RubyInterface {
151151
try {
152152
await this.runManagerActivation();
153153
} catch (error: any) {
154-
if (!(error instanceof UntrustedWorkspaceError)) {
154+
if (!(error instanceof NonReportableError)) {
155155
this.telemetry.logError(error, {
156156
appType: "extension",
157157
appVersion: this.context.extension.packageJSON.version,

vscode/src/ruby/chruby.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as vscode from "vscode";
55

66
import { WorkspaceChannel } from "../workspaceChannel";
77

8-
import { ActivationResult, VersionManager, ACTIVATION_SEPARATOR } from "./versionManager";
8+
import { ActivationResult, MissingRubyError, VersionManager, ACTIVATION_SEPARATOR } from "./versionManager";
99

1010
interface RubyVersion {
1111
engine?: string;
@@ -226,7 +226,7 @@ export class Chruby extends VersionManager {
226226
return closest;
227227
}
228228

229-
throw new Error("Cannot find any Ruby installations");
229+
throw new MissingRubyError("Cannot find any Ruby installations");
230230
}
231231

232232
// Returns the Ruby version information including version and engine. E.g.: ruby-3.3.0, truffleruby-21.3.0
@@ -429,7 +429,7 @@ export class Chruby extends VersionManager {
429429
}
430430

431431
private missingRubyError(version: string) {
432-
return new Error(`Cannot find Ruby installation for version ${version}`);
432+
return new MissingRubyError(`Cannot find Ruby installation for version ${version}`);
433433
}
434434

435435
private rubyVersionError() {

vscode/src/ruby/rubyInstaller.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import os from "os";
33
import * as vscode from "vscode";
44

55
import { Chruby } from "./chruby";
6+
import { MissingRubyError } from "./versionManager";
67

78
interface RubyVersion {
89
engine?: string;
@@ -40,7 +41,7 @@ export class RubyInstaller extends Chruby {
4041
}
4142
}
4243

43-
throw new Error(
44+
throw new MissingRubyError(
4445
`Cannot find installation directory for Ruby version ${rubyVersion.version}.\
4546
Searched in ${possibleInstallationUris.map((uri) => uri.fsPath).join(", ")}`,
4647
);

vscode/src/ruby/shadowenv.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import * as vscode from "vscode";
22

33
import { asyncExec } from "../common";
44

5-
import { VersionManager, ActivationResult } from "./versionManager";
5+
import { VersionManager, ActivationResult, NonReportableError } from "./versionManager";
66

77
// Shadowenv is a tool that allows managing environment variables upon entering a directory. It allows users to manage
88
// which Ruby version should be used for each project, in addition to other customizations such as GEM_HOME.
99
//
1010
// Learn more: https://github.com/Shopify/shadowenv
11-
export class UntrustedWorkspaceError extends Error {}
11+
export class UntrustedWorkspaceError extends NonReportableError {}
1212

1313
export class Shadowenv extends VersionManager {
1414
async activate(): Promise<ActivationResult> {

vscode/src/ruby/versionManager.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ export interface ActivationResult {
1313
gemPath: string[];
1414
}
1515

16+
export class NonReportableError extends Error {}
17+
export class MissingRubyError extends NonReportableError {}
18+
1619
// Changes to either one of these values have to be synchronized with a corresponding update in `activation.rb`
1720
export const ACTIVATION_SEPARATOR = "RUBY_LSP_ACTIVATION_SEPARATOR";
1821
export const VALUE_SEPARATOR = "RUBY_LSP_VS";

vscode/src/test/suite/ruby.test.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import { WorkspaceChannel } from "../../workspaceChannel";
1212
import { LOG_CHANNEL } from "../../common";
1313
import * as common from "../../common";
1414
import { Shadowenv, UntrustedWorkspaceError } from "../../ruby/shadowenv";
15-
import { ACTIVATION_SEPARATOR, FIELD_SEPARATOR, VALUE_SEPARATOR } from "../../ruby/versionManager";
15+
import { Chruby } from "../../ruby/chruby";
16+
import { ACTIVATION_SEPARATOR, FIELD_SEPARATOR, MissingRubyError, VALUE_SEPARATOR } from "../../ruby/versionManager";
1617

1718
import { createContext, FakeContext } from "./helpers";
1819
import { FAKE_TELEMETRY } from "./fakeTelemetry";
@@ -146,6 +147,21 @@ suite("Ruby environment activation", () => {
146147
assert.ok(!telemetry.logError.called);
147148
});
148149

150+
test("Ignores missing Ruby version for telemetry", async () => {
151+
const telemetry = { ...FAKE_TELEMETRY, logError: sandbox.stub() };
152+
const ruby = new Ruby(context, workspaceFolder, outputChannel, telemetry);
153+
154+
sandbox
155+
.stub(Chruby.prototype, "activate")
156+
.rejects(new MissingRubyError("Cannot find Ruby installation for version 3.4.0"));
157+
158+
await assert.rejects(async () => {
159+
await ruby.activateRuby({ identifier: ManagerIdentifier.Chruby });
160+
});
161+
162+
assert.ok(!telemetry.logError.called);
163+
});
164+
149165
test("Clears outdated workspace Ruby path caches", async () => {
150166
const manager = process.env.CI ? ManagerIdentifier.None : ManagerIdentifier.Chruby;
151167

0 commit comments

Comments
 (0)