diff --git a/vscode/src/ruby.ts b/vscode/src/ruby.ts index 490d027d6e..3405a1973d 100644 --- a/vscode/src/ruby.ts +++ b/vscode/src/ruby.ts @@ -5,9 +5,9 @@ import * as vscode from "vscode"; import { asyncExec, RubyInterface } from "./common"; import { WorkspaceChannel } from "./workspaceChannel"; -import { Shadowenv, UntrustedWorkspaceError } from "./ruby/shadowenv"; +import { Shadowenv } from "./ruby/shadowenv"; import { Chruby } from "./ruby/chruby"; -import { VersionManager } from "./ruby/versionManager"; +import { NonReportableError, VersionManager } from "./ruby/versionManager"; import { Mise } from "./ruby/mise"; import { RubyInstaller } from "./ruby/rubyInstaller"; import { Rbenv } from "./ruby/rbenv"; @@ -151,7 +151,7 @@ export class Ruby implements RubyInterface { try { await this.runManagerActivation(); } catch (error: any) { - if (!(error instanceof UntrustedWorkspaceError)) { + if (!(error instanceof NonReportableError)) { this.telemetry.logError(error, { appType: "extension", appVersion: this.context.extension.packageJSON.version, diff --git a/vscode/src/ruby/chruby.ts b/vscode/src/ruby/chruby.ts index dc1f73a589..efc33ce86f 100644 --- a/vscode/src/ruby/chruby.ts +++ b/vscode/src/ruby/chruby.ts @@ -5,7 +5,7 @@ import * as vscode from "vscode"; import { WorkspaceChannel } from "../workspaceChannel"; -import { ActivationResult, VersionManager, ACTIVATION_SEPARATOR } from "./versionManager"; +import { ActivationResult, MissingRubyError, VersionManager, ACTIVATION_SEPARATOR } from "./versionManager"; interface RubyVersion { engine?: string; @@ -226,7 +226,7 @@ export class Chruby extends VersionManager { return closest; } - throw new Error("Cannot find any Ruby installations"); + throw new MissingRubyError("Cannot find any Ruby installations"); } // Returns the Ruby version information including version and engine. E.g.: ruby-3.3.0, truffleruby-21.3.0 @@ -425,11 +425,11 @@ export class Chruby extends VersionManager { } } - throw new Error("Cannot find any Ruby installations"); + throw new MissingRubyError("Cannot find any Ruby installations"); } private missingRubyError(version: string) { - return new Error(`Cannot find Ruby installation for version ${version}`); + return new MissingRubyError(`Cannot find Ruby installation for version ${version}`); } private rubyVersionError() { diff --git a/vscode/src/ruby/rubyInstaller.ts b/vscode/src/ruby/rubyInstaller.ts index 3adc0503bb..667dcdcdd9 100644 --- a/vscode/src/ruby/rubyInstaller.ts +++ b/vscode/src/ruby/rubyInstaller.ts @@ -3,6 +3,7 @@ import os from "os"; import * as vscode from "vscode"; import { Chruby } from "./chruby"; +import { MissingRubyError } from "./versionManager"; interface RubyVersion { engine?: string; @@ -40,7 +41,7 @@ export class RubyInstaller extends Chruby { } } - throw new Error( + throw new MissingRubyError( `Cannot find installation directory for Ruby version ${rubyVersion.version}.\ Searched in ${possibleInstallationUris.map((uri) => uri.fsPath).join(", ")}`, ); diff --git a/vscode/src/ruby/shadowenv.ts b/vscode/src/ruby/shadowenv.ts index a683ad8e2f..38da3e87d2 100644 --- a/vscode/src/ruby/shadowenv.ts +++ b/vscode/src/ruby/shadowenv.ts @@ -2,13 +2,13 @@ import * as vscode from "vscode"; import { asyncExec } from "../common"; -import { VersionManager, ActivationResult } from "./versionManager"; +import { VersionManager, ActivationResult, NonReportableError } from "./versionManager"; // Shadowenv is a tool that allows managing environment variables upon entering a directory. It allows users to manage // which Ruby version should be used for each project, in addition to other customizations such as GEM_HOME. // // Learn more: https://github.com/Shopify/shadowenv -export class UntrustedWorkspaceError extends Error {} +export class UntrustedWorkspaceError extends NonReportableError {} export class Shadowenv extends VersionManager { async activate(): Promise { diff --git a/vscode/src/ruby/versionManager.ts b/vscode/src/ruby/versionManager.ts index 52fa4b94f0..97c7f44f19 100644 --- a/vscode/src/ruby/versionManager.ts +++ b/vscode/src/ruby/versionManager.ts @@ -13,6 +13,9 @@ export interface ActivationResult { gemPath: string[]; } +export class NonReportableError extends Error {} +export class MissingRubyError extends NonReportableError {} + // Changes to either one of these values have to be synchronized with a corresponding update in `activation.rb` export const ACTIVATION_SEPARATOR = "RUBY_LSP_ACTIVATION_SEPARATOR"; export const VALUE_SEPARATOR = "RUBY_LSP_VS"; diff --git a/vscode/src/test/suite/ruby.test.ts b/vscode/src/test/suite/ruby.test.ts index 37485c1acb..e0a093c179 100644 --- a/vscode/src/test/suite/ruby.test.ts +++ b/vscode/src/test/suite/ruby.test.ts @@ -12,7 +12,8 @@ import { WorkspaceChannel } from "../../workspaceChannel"; import { LOG_CHANNEL } from "../../common"; import * as common from "../../common"; import { Shadowenv, UntrustedWorkspaceError } from "../../ruby/shadowenv"; -import { ACTIVATION_SEPARATOR, FIELD_SEPARATOR, VALUE_SEPARATOR } from "../../ruby/versionManager"; +import { Chruby } from "../../ruby/chruby"; +import { ACTIVATION_SEPARATOR, FIELD_SEPARATOR, MissingRubyError, VALUE_SEPARATOR } from "../../ruby/versionManager"; import { createContext, FakeContext } from "./helpers"; import { FAKE_TELEMETRY } from "./fakeTelemetry"; @@ -146,6 +147,21 @@ suite("Ruby environment activation", () => { assert.ok(!telemetry.logError.called); }); + test("Ignores missing Ruby version for telemetry", async () => { + const telemetry = { ...FAKE_TELEMETRY, logError: sandbox.stub() }; + const ruby = new Ruby(context, workspaceFolder, outputChannel, telemetry); + + sandbox + .stub(Chruby.prototype, "activate") + .rejects(new MissingRubyError("Cannot find Ruby installation for version 3.4.0")); + + await assert.rejects(async () => { + await ruby.activateRuby({ identifier: ManagerIdentifier.Chruby }); + }); + + assert.ok(!telemetry.logError.called); + }); + test("Clears outdated workspace Ruby path caches", async () => { const manager = process.env.CI ? ManagerIdentifier.None : ManagerIdentifier.Chruby;