Repository: confluentinc/vscode
Pull request #1930: Reduce complexity, write new tests over deleteConnection().
Author: login: jlrobins
Created: 2025-05-29T17:30:59Z | Merged: 2025-05-29T21:46:19Z

## Summary of Changes

<!-- Include a high-level overview of your implementation, including any alternatives you considered and items you'll address in follow-up PRs -->

- Address some of the many concerns flagged by [SonarCube](https://sonarqube.dp.confluent.io/dashboard?id=vscode):
  - Reduce complexity of the direct connection secret store event handler by moving most of it to a separate function.
  - Write new tests over DirectConnectionManager.deleteConnection(), was missing coverage. Handle 'connection id not found' better in there while there.
  - Fix many 'return statement unneeded'
  - Fix many 'assertion or type reassignment unneeded'

## Any additional details or context that should be provided?

<!-- Behavior before/after, more technical details/screenshots, follow-on work that should be expected, links to discussions or issues, etc -->

- Closes #1927 

## Pull request checklist

Please check if your PR fulfills the following (if applicable):

##### Tests

- [x] Added new
- [ ] Updated existing
- [ ] Deleted existing

##### Other

- [ ] All new disposables (event listeners, views, channels, etc.) collected as  for eventual cleanup?
<!-- prettier-ignore -->
- [ ] Does anything in this PR need to be mentioned in the user-facing [CHANGELOG](https://github.com/confluentinc/vscode/blob/main/CHANGELOG.md) or [README](https://github.com/confluentinc/vscode/blob/main/public/README.md)?
- [ ] Have you validated this change locally by [packaging](https://github.com/confluentinc/vscode/blob/main/README.md#packaging-steps) and installing the extension `.vsix` file?
  ```shell
  gulp clicktest
  ```


Linked issue #1927: Address low-hanging friut from sonarcube 'bug' report
Misc issues reported, mostly one-line changes scattered throughout codebase. Triage and pick off some, ensuring or adding test coverage as going along.

Diff:
diff --git a/src/authn/ccloudProvider.ts b/src/authn/ccloudProvider.ts
index eec4a1e358..2ed51b163d 100644
--- a/src/authn/ccloudProvider.ts
+++ b/src/authn/ccloudProvider.ts
@@ -513,7 +513,7 @@ export class ConfluentCloudAuthProvider implements vscode.AuthenticationProvider
     } else {
       this._onDidChangeSessions.fire({
         added: [],
-        removed: [this._session!],
+        removed: [this._session],
         changed: [],
       });
       this._session = null;
diff --git a/src/authz/types.ts b/src/authz/types.ts
index f934990ea3..6ff91a6824 100644
--- a/src/authz/types.ts
+++ b/src/authz/types.ts
@@ -9,5 +9,5 @@ export function toKafkaTopicOperations(operations: string[]): KafkaTopicOperatio
     KAFKA_TOPIC_OPERATIONS.includes(op as KafkaTopicOperation),
   );
 
-  return validOperations as KafkaTopicOperation[];
+  return validOperations;
 }
diff --git a/src/chat/participant.ts b/src/chat/participant.ts
index ee2d88b098..1df89858cb 100644
--- a/src/chat/participant.ts
+++ b/src/chat/participant.ts
@@ -287,7 +287,7 @@ export async function handleChatMessage(
         stream.markdown(fragment.value);
       } else if (fragment instanceof LanguageModelToolCallPart) {
         // tool call: look up the tool from the map, process its invocation result(s), and continue on
-        const toolCall: LanguageModelToolCallPart = fragment as LanguageModelToolCallPart;
+        const toolCall: LanguageModelToolCallPart = fragment;
         const tool: BaseLanguageModelTool<any> | undefined = getToolMap().get(toolCall.name);
         logUsage(UserEvent.CopilotInteraction, {
           status: "tool call received from model",
diff --git a/src/chat/tools/getConnections.ts b/src/chat/tools/getConnections.ts
index c65620d08c..b7ce648c4a 100644
--- a/src/chat/tools/getConnections.ts
+++ b/src/chat/tools/getConnections.ts
@@ -42,6 +42,7 @@ export class GetConnectionsTool extends BaseLanguageModelTool<IGetConnectionsPar
 
   prepareInvocation(
     options: LanguageModelToolInvocationPrepareOptions<IGetConnectionsParameters>,
+    // eslint-disable-next-line @typescript-eslint/no-unused-vars
     token: CancellationToken,
   ): ProviderResult<PreparedToolInvocation> {
     const { input } = options;
diff --git a/src/commands/index.ts b/src/commands/index.ts
index 2ceb3dc2f3..9f172b61cc 100644
--- a/src/commands/index.ts
+++ b/src/commands/index.ts
@@ -27,7 +27,7 @@ export function registerCommandWithLogging(
       ...getCommandArgsContext(args),
     });
     try {
-      return await command(...args);
+      return command(...args);
     } catch (e) {
       if (e instanceof Error) {
         // gather more (possibly-ResponseError) context and send to Sentry (only enabled in
diff --git a/src/commands/schemaUpload.ts b/src/commands/schemaUpload.ts
index 383a71c33e..b3abc0cd1e 100644
--- a/src/commands/schemaUpload.ts
+++ b/src/commands/schemaUpload.ts
@@ -181,7 +181,7 @@ async function uploadSchema(
   }
 
   // Log + inform user of the successful schema registration, give them the option to view the schema in the schema registry.
-  const successMessage = schemaRegistrationMessage(subject, existingVersion, registeredVersion!);
+  const successMessage = schemaRegistrationMessage(subject, existingVersion, registeredVersion);
 
   logger.info(successMessage);
 
@@ -257,7 +257,6 @@ export function validateNewSubject(
       severity: vscode.InputBoxValidationSeverity.Warning,
     };
   }
-  return;
 }
 
 /** Given the error message from a 409 conflict when trying to upload a new schema, extract
diff --git a/src/commands/utils/flinkStatements.ts b/src/commands/utils/flinkStatements.ts
index 211801af67..a67e9a2d01 100644
--- a/src/commands/utils/flinkStatements.ts
+++ b/src/commands/utils/flinkStatements.ts
@@ -156,5 +156,5 @@ export async function submitFlinkStatement(
  */
 export function localTimezoneOffset(): string {
   const nowStr = new Date().toString();
-  return nowStr.match(/([A-Z]+[+-][0-9]+)/)![1];
+  return nowStr.match(/([A-Z]+[+-]\d+)/)![1]; //NOSONAR: This regex is safe for parsing the timezone offset from a date string.
 }
diff --git a/src/consume.ts b/src/consume.ts
index 5dc17efbb0..70cf7b53fb 100644
--- a/src/consume.ts
+++ b/src/consume.ts
@@ -164,7 +164,7 @@ export function activateMessageViewer(context: ExtensionContext) {
           if (envId == null) {
             return window.showErrorMessage("Unable to open Message Viewer: URI is malformed");
           }
-          loader = DirectResourceLoader.getInstance(envId! as ConnectionId);
+          loader = DirectResourceLoader.getInstance(envId as ConnectionId);
           break;
         default:
           return window.showErrorMessage("Unable to open Message Viewer: URI is malformed");
diff --git a/src/directConnect.ts b/src/directConnect.ts
index 0b73ef8e6d..f18d3b32c8 100644
--- a/src/directConnect.ts
+++ b/src/directConnect.ts
@@ -41,9 +41,7 @@ export async function handleConnectionChange(
   if (!existingConnections) {
     window.showInformationMessage(`Connection "${connection.name}" is disconnected.`);
     directConnectForm.dispose();
-    return;
   }
-  return;
 }
 
 export function openDirectConnectionForm(connection: CustomConnectionSpec | null): void {
diff --git a/src/directConnectManager.test.ts b/src/directConnectManager.test.ts
index 2d18658f07..2906467594 100644
--- a/src/directConnectManager.test.ts
+++ b/src/directConnectManager.test.ts
@@ -14,6 +14,7 @@ import {
   ResponseError,
 } from "./clients/sidecar";
 import { DirectConnectionManager } from "./directConnectManager";
+import { ResourceLoader } from "./loaders";
 import { ConnectionId } from "./models/resource";
 import * as sidecar from "./sidecar";
 import * as connections from "./sidecar/connections";
@@ -49,6 +50,7 @@ describe("DirectConnectionManager behavior", () => {
   let tryToUpdateConnectionStub: sinon.SinonStub;
 
   let stubbedConnectionsResourceApi: sinon.SinonStubbedInstance<ConnectionsResourceApi>;
+  let waitForConnectionToBeStableStub: sinon.SinonStub;
 
   before(async () => {
     // DirectConnectionManager requires the extension context to be set
@@ -72,8 +74,11 @@ describe("DirectConnectionManager behavior", () => {
     tryToUpdateConnectionStub = sandbox
       .stub(connections, "tryToUpdateConnection")
       .resolves({} as any);
+
     // assume the connection is immediately usable for most tests
-    sandbox.stub(watcher, "waitForConnectionToBeStable").resolves(TEST_DIRECT_CONNECTION);
+    waitForConnectionToBeStableStub = sandbox
+      .stub(watcher, "waitForConnectionToBeStable")
+      .resolves(TEST_DIRECT_CONNECTION);
   });
 
   afterEach(async () => {
@@ -254,6 +259,12 @@ describe("DirectConnectionManager behavior", () => {
       ConnectionSpecFromJSON(args[0]),
       ConnectionSpecFromJSON(TEST_DIRECT_CONNECTION_FORM_SPEC),
     );
+
+    sinon.assert.calledOnce(waitForConnectionToBeStableStub);
+    sinon.assert.calledWith(
+      waitForConnectionToBeStableStub,
+      TEST_DIRECT_CONNECTION.spec.id as ConnectionId,
+    );
   });
 
   it("rehydrateConnections() should not inform the sidecar of existing/tracked connections", async () => {
@@ -270,4 +281,43 @@ describe("DirectConnectionManager behavior", () => {
 
     assert.ok(tryToCreateConnectionStub.notCalled);
   });
+
+  describe("deleteConnection()", () => {
+    const TEST_DIRECT_CONNECTION_ID = TEST_DIRECT_CONNECTION.spec.id as ConnectionId;
+
+    let directConnectionManager: DirectConnectionManager;
+
+    beforeEach(() => {
+      // Can only be done after the extension context is set.
+      directConnectionManager = DirectConnectionManager.getInstance();
+    });
+
+    it("should handle if getDirectConnection(id) returned null", async () => {
+      const rm = getResourceManager();
+      sandbox.stub(rm, "getDirectConnection").resolves(null);
+
+      await directConnectionManager.deleteConnection(TEST_DIRECT_CONNECTION_ID);
+    });
+
+    it("should work if getDirectConnection(id) returned a connection", async () => {
+      const rm = getResourceManager();
+      sandbox.stub(rm, "getDirectConnection").resolves(TEST_DIRECT_CONNECTION_FORM_SPEC);
+      const deleteStub = sandbox.stub(rm, "deleteDirectConnection").resolves();
+      const tryToDeleteConnectionStub = sandbox
+        .stub(connections, "tryToDeleteConnection")
+        .resolves({} as any);
+
+      const deregisterInstanceStub = sandbox.stub(ResourceLoader, "deregisterInstance");
+
+      await directConnectionManager.deleteConnection(TEST_DIRECT_CONNECTION_ID);
+      sinon.assert.calledOnce(deleteStub);
+      sinon.assert.calledWith(deleteStub, TEST_DIRECT_CONNECTION_ID);
+
+      sinon.assert.calledOnce(tryToDeleteConnectionStub);
+      sinon.assert.calledWith(tryToDeleteConnectionStub, TEST_DIRECT_CONNECTION_ID);
+
+      sinon.assert.calledOnce(deregisterInstanceStub);
+      sinon.assert.calledWith(deregisterInstanceStub, TEST_DIRECT_CONNECTION_ID);
+    });
+  });
 });
diff --git a/src/directConnectManager.ts b/src/directConnectManager.ts
index af53a391e9..ad4afe9e81 100644
--- a/src/directConnectManager.ts
+++ b/src/directConnectManager.ts
@@ -68,67 +68,14 @@ export class DirectConnectionManager {
   }
 
   private setEventListeners(): Disposable[] {
+    // Register to call handleDirectConnectionsChanged() if the direct connections
+    // key in SecretStorage changes, which happens when a direct connection is added, edited,
+    // or deleted in the webview form, by either this or another workspace.
     const connectionsListener: Disposable = getSecretStorage().onDidChange(
       async ({ key }: SecretStorageChangeEvent) => {
-        // watch for any cross-workspace direct connection additions/removals
+        // watch for any cross-workspace (or self-made) direct connection additions/removals
         if (key === SecretStorageKeys.DIRECT_CONNECTIONS) {
-          const connections: DirectConnectionsById =
-            await getResourceManager().getDirectConnections();
-          // ensure all DirectResourceLoader instances are up to date.
-
-          // part 1: ensure any new connections have registered loaders; if this isn't done, hopping
-          // workspaces and attempting to focus on a direct connection-based resource will fail with
-          // the `Unknown connection ID` error. And purge the cache of any existing loaders
-          // so they can re-fetch the latest resources, which may have just been reconfigured.
-
-          const existingDirectLoadersById: Map<ConnectionId, DirectResourceLoader> = new Map(
-            ResourceLoader.directLoaders().map((loader) => [loader.connectionId, loader]),
-          );
-
-          const existingLoaderIds: ConnectionId[] = Array.from(existingDirectLoadersById.keys());
-
-          // Either make new loaders for any connections that don't have one, or
-          // purge the cache of existing loaders to ensure they re-fetch the latest resources next time
-          // (may have been reconfigured, e.g. new kafka cluster or schema registry, or improved)
-          for (const id of connections.keys()) {
-            if (!existingDirectLoadersById.has(id)) {
-              this.initResourceLoader(id);
-            } else {
-              // Get this preexisting loader to purge its cache, so it can re-fetch the latest resources. The
-              // connection may have gained or lost kafka cluster or schema registry, or improved
-              // the spelling of which. Alas we don't know if this connection was changed at all when
-              // we get the change event, so we have to be conservative and purge the caches of any
-              // existing direct loaders.
-              const existingLoader = existingDirectLoadersById.get(id)!;
-              existingLoader.purgeCache();
-            }
-          }
-
-          // part 2: remove any direct connections not in the secret storage to prevent
-          // requests to orphaned resources/connections
-          for (const id of existingLoaderIds) {
-            if (!connections.has(id)) {
-              ResourceLoader.deregisterInstance(id);
-            }
-          }
-
-          // this is mainly to inform the Resources view to refresh its list of connections
-          directConnectionsChanged.fire();
-
-          // if the Topics/Schemas views were focused on a resource whose direct connection was removed,
-          // reset the view(s) to prevent orphaned resources from being used for requests
-          const topicsView = getTopicViewProvider();
-          if (topicsView.kafkaCluster && isDirect(topicsView.kafkaCluster)) {
-            if (!connections.has(topicsView.kafkaCluster.connectionId)) {
-              topicsView.reset();
-            }
-          }
-          const schemasView = getSchemasViewProvider();
-          if (schemasView.schemaRegistry && isDirect(schemasView.schemaRegistry)) {
-            if (!connections.has(schemasView.schemaRegistry.connectionId)) {
-              await schemasView.reset();
-            }
-          }
+          await this.handleDirectConnectionsChanged();
         }
       },
     );
@@ -136,6 +83,70 @@ export class DirectConnectionManager {
     return [connectionsListener];
   }
 
+  /**
+   * Handle changes made to the direct connections in the SecretStorage, either from other
+   * workspaces or changes that this workspace just performed.
+   */
+  private async handleDirectConnectionsChanged(): Promise<void> {
+    const connections: DirectConnectionsById = await getResourceManager().getDirectConnections();
+    // Ensure all DirectResourceLoader instances are up to date.
+
+    // Part 1: ensure any new connections have registered loaders; if this isn't done, hopping
+    // workspaces and attempting to focus on a direct connection-based resource will fail with
+    // the `Unknown connection ID` error. And purge the cache of any existing loaders
+    // so they can re-fetch the latest resources, which may have just been reconfigured.
+
+    const existingDirectLoadersById: Map<ConnectionId, DirectResourceLoader> = new Map(
+      ResourceLoader.directLoaders().map((loader) => [loader.connectionId, loader]),
+    );
+
+    const existingLoaderIds: ConnectionId[] = Array.from(existingDirectLoadersById.keys());
+
+    // Either make new loaders for any connections that don't have one, or
+    // purge the cache of existing loaders to ensure they re-fetch the latest resources next time
+    // (may have been reconfigured, e.g. new kafka cluster or schema registry, or improved)
+    for (const id of connections.keys()) {
+      if (!existingDirectLoadersById.has(id)) {
+        this.initResourceLoader(id);
+      } else {
+        // Get this preexisting loader to purge its cache, so it can re-fetch the latest resources. The
+        // connection may have gained or lost kafka cluster or schema registry, or improved
+        // the spelling of which. Alas we don't know if this connection was changed at all when
+        // we get the change event, so we have to be conservative and purge the caches of any
+        // existing direct loaders.
+        const existingLoader = existingDirectLoadersById.get(id)!;
+        existingLoader.purgeCache();
+      }
+    }
+
+    // Part 2: remove any direct connections not in the secret storage to prevent
+    // requests to orphaned resources/connections
+    for (const id of existingLoaderIds) {
+      if (!connections.has(id)) {
+        ResourceLoader.deregisterInstance(id);
+      }
+    }
+
+    // Inform the Resources view to refresh its list of connections
+    directConnectionsChanged.fire();
+
+    // If the Topics/Schemas views were focused on a resource whose direct connection was removed,
+    // reset the view(s) to prevent orphaned resources from being used for requests
+    const topicsView = getTopicViewProvider();
+    if (topicsView.kafkaCluster && isDirect(topicsView.kafkaCluster)) {
+      if (!connections.has(topicsView.kafkaCluster.connectionId)) {
+        topicsView.reset();
+      }
+    }
+
+    const schemasView = getSchemasViewProvider();
+    if (schemasView.schemaRegistry && isDirect(schemasView.schemaRegistry)) {
+      if (!connections.has(schemasView.schemaRegistry.connectionId)) {
+        await schemasView.reset();
+      }
+    }
+  }
+
   /**
    * Create a new direct connection with the configurations provided from the webview form.
    * @see `src/directConnect.ts` for the form data processing.
@@ -179,19 +190,27 @@ export class DirectConnectionManager {
   }
 
   async deleteConnection(id: ConnectionId): Promise<void> {
-    const spec: CustomConnectionSpec | null = await getResourceManager().getDirectConnection(id);
-    await Promise.all([getResourceManager().deleteDirectConnection(id), tryToDeleteConnection(id)]);
+    const resourceManager = getResourceManager();
+    const spec: CustomConnectionSpec | null = await resourceManager.getDirectConnection(id);
+
+    if (!spec) {
+      // Wacky, shouldn't happen, but if it does, just log and return.
+      logger.warn(`Tried to delete a direct connection with ID ${id}, but it does not exist.`);
+      return;
+    }
+
+    await Promise.all([resourceManager.deleteDirectConnection(id), tryToDeleteConnection(id)]);
 
     logUsage(UserEvent.DirectConnectionAction, {
       action: "deleted",
-      type: spec?.formConnectionType,
+      type: spec.formConnectionType,
       specifiedConnectionType: spec?.specifiedConnectionType,
-      withKafka: !!spec?.kafka_cluster,
-      withSchemaRegistry: !!spec?.schema_registry,
-      kafkaAuthType: getCredentialsType(spec?.kafka_cluster?.credentials),
-      kafkaSslEnabled: spec?.kafka_cluster?.ssl?.enabled,
-      schemaRegistryAuthType: getCredentialsType(spec?.schema_registry?.credentials),
-      schemaRegistrySslEnabled: spec?.schema_registry?.ssl?.enabled,
+      withKafka: !!spec.kafka_cluster,
+      withSchemaRegistry: !!spec.schema_registry,
+      kafkaAuthType: getCredentialsType(spec.kafka_cluster?.credentials),
+      kafkaSslEnabled: spec.kafka_cluster?.ssl?.enabled,
+      schemaRegistryAuthType: getCredentialsType(spec.schema_registry?.credentials),
+      schemaRegistrySslEnabled: spec.schema_registry?.ssl?.enabled,
     });
 
     ResourceLoader.deregisterInstance(id);
@@ -221,7 +240,6 @@ export class DirectConnectionManager {
 
     // update the connection in secret storage (via full replace of the connection by its id)
     await getResourceManager().addDirectConnection(incomingSpec);
-    return;
   }
 
   /**
@@ -264,7 +282,8 @@ export class DirectConnectionManager {
       } else if (error instanceof Error) {
         errorMessage = error.message;
       }
-      const msg = `Failed to ${update ? "update" : dryRun ? "test" : "create"} connection. ${errorMessage}`;
+      const testOrCreate = dryRun ? "test" : "create";
+      const msg = `Failed to ${update ? "update" : testOrCreate} connection. ${errorMessage}`;
       logger.error(msg);
       if (!dryRun) window.showErrorMessage(msg);
       errorMessage = msg;
@@ -321,7 +340,7 @@ export class DirectConnectionManager {
       // wait for all new connections to be created before checking their status
       await Promise.all(newConnectionPromises);
       // kick off background checks to ensure the new connections are usable
-      connectionIdsToCheck.map((id) => waitForConnectionToBeStable(id));
+      connectionIdsToCheck.forEach((id) => void waitForConnectionToBeStable(id));
       logger.debug(
         `created and checked ${connectionIdsToCheck.length} new connection(s), firing event`,
       );
diff --git a/src/docker/workflows/confluent-local.ts b/src/docker/workflows/confluent-local.ts
index efb1dace32..4457ded6ca 100644
--- a/src/docker/workflows/confluent-local.ts
+++ b/src/docker/workflows/confluent-local.ts
@@ -366,7 +366,6 @@ export function validateBrokerInput(userInput: string): InputBoxValidationMessag
       severity: InputBoxValidationSeverity.Error,
     };
   }
-  return;
 }
 
 export interface KafkaContainerPorts {
diff --git a/src/docker/workflows/cp-schema-registry.ts b/src/docker/workflows/cp-schema-registry.ts
index df4341cd43..c396e46f32 100644
--- a/src/docker/workflows/cp-schema-registry.ts
+++ b/src/docker/workflows/cp-schema-registry.ts
@@ -121,7 +121,7 @@ export class ConfluentPlatformSchemaRegistryWorkflow extends LocalResourceWorkfl
     }
     // inspect the containers to get the Docker network name and boostrap server host+port combos
     const kafkaNetworks: string[] = determineKafkaDockerNetworks(kafkaContainers);
-    const kafkaBootstrapServers = await determineKafkaBootstrapServers(kafkaContainers);
+    const kafkaBootstrapServers = determineKafkaBootstrapServers(kafkaContainers);
     this.logger.debug("Kafka container(s) found", {
       count: kafkaContainers.length,
       bootstrapServers: kafkaBootstrapServers,
diff --git a/src/errors.ts b/src/errors.ts
index e23b9d9fd3..faf99f95fd 100644
--- a/src/errors.ts
+++ b/src/errors.ts
@@ -65,11 +65,11 @@ export async function extractResponseBody(error: AnyResponseError): Promise<any>
     throw new Error("extractResponseBody() called with non-ResponseError");
   }
 
-  const responseError = error as AnyResponseError;
+  // Attempt to parse the response body as JSON, falling back to text if it fails
   try {
-    return await responseError.response.clone().json();
+    return await error.response.clone().json();
   } catch {
-    return await responseError.response.clone().text();
+    return await error.response.clone().text();
   }
 }
 
@@ -139,7 +139,7 @@ export async function logError(
 
   /** Light wrapper around the original error, used to update the name/message for easier debugging
    * and event tracking in Sentry. */
-  let wrappedError: Error = e as Error;
+  let wrappedError: Error;
   /** Used to add extra/additional data to the Sentry exception */
   let errorContext: Record<string, string | number | boolean | null | undefined> = {};
   /** Used to set the `contexts.response.status_code` for the Sentry exception */
diff --git a/src/extension.ts b/src/extension.ts
index 98a9eebf9c..3c0072ba55 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -2,7 +2,7 @@ import * as vscode from "vscode";
 /** First things first, setup Sentry to catch errors during activation and beyond
  * `process.env.SENTRY_DSN` is fetched & defined during production builds only for Confluent official release process
  * */
-import { closeSentryClient, initSentry } from "./telemetry/sentryClient";
+import { closeSentryClient, initSentry, sentryCaptureException } from "./telemetry/sentryClient";
 if (process.env.SENTRY_DSN) {
   initSentry();
 }
@@ -71,7 +71,6 @@ import { getCCloudStatusBarItem } from "./statusBar/ccloudItem";
 import { SecretStorageKeys } from "./storage/constants";
 import { migrateStorageIfNeeded } from "./storage/migrationManager";
 import { logUsage, UserEvent } from "./telemetry/events";
-import { sentryCaptureException } from "./telemetry/sentryClient";
 import { sendTelemetryIdentifyEvent } from "./telemetry/telemetry";
 import { getTelemetryLogger } from "./telemetry/telemetryLogger";
 import { getUriHandler } from "./uriHandler";
diff --git a/src/flinkSql/flinkStatementManager.ts b/src/flinkSql/flinkStatementManager.ts
index a66f966ed8..4916546359 100644
--- a/src/flinkSql/flinkStatementManager.ts
+++ b/src/flinkSql/flinkStatementManager.ts
@@ -221,7 +221,6 @@ export class FlinkStatementManager {
         const newConcurrency = workspaceConfigs.get<number>(STATEMENT_POLLING_CONCURRENCY)!;
         this.configuration.concurrency = newConcurrency;
         logger.debug(`Polling concurrency changed to ${newConcurrency}`);
-        return;
       }
     });
   }
diff --git a/src/sidecar/logging.ts b/src/sidecar/logging.ts
index 54ba85d0d7..70370b45c8 100644
--- a/src/sidecar/logging.ts
+++ b/src/sidecar/logging.ts
@@ -50,7 +50,8 @@ export function startTailingSidecarLogs(): Tail | undefined {
 
   // Take note of the start of exception lines in the log file, show as toast (if user has allowed via config)
   // Define a regex pattern to find "ERROR", a parenthesized thread name, and capture everything after it
-  const regex = /ERROR.*\(([^)]+)\)\s*(.*)$/;
+
+  const regex = /ERROR.*\(([^)]+)\)\s*(.*)$/; //NOSONAR: This regex is intentionally written for log parsing and is safe in this context.
 
   logTailer.on("line", (data: any) => {
     const line: string = data.toString();
diff --git a/src/utils/workerPool.test.ts b/src/utils/workerPool.test.ts
index e68a2bc094..2afd0c7501 100644
--- a/src/utils/workerPool.test.ts
+++ b/src/utils/workerPool.test.ts
@@ -216,7 +216,7 @@ describe("utils/workerPool.ts extract() tests", () => {
 
     assert.throws(
       () => {
-        const goodResults: number[] = extract(results);
+        extract(results);
       },
       { message: "test error 2" },
     );
diff --git a/src/webview/scaffold-form.ts b/src/webview/scaffold-form.ts
index 7b880aef42..89d45be1d5 100644
--- a/src/webview/scaffold-form.ts
+++ b/src/webview/scaffold-form.ts
@@ -39,7 +39,9 @@ class ScaffoldFormViewModel extends ViewModel {
 
   options = this.derive(() => {
     const allOptions = Object.entries(this.spec()?.options ?? {});
+    // eslint-disable-next-line @typescript-eslint/no-unused-vars
     const orderedOptions = allOptions.filter(([_, details]) => details.order !== undefined);
+    // eslint-disable-next-line @typescript-eslint/no-unused-vars
     const unorderedOptions = allOptions.filter(([_, details]) => details.order === undefined);
     orderedOptions.sort((a, b) => (a[1].order ?? 0) - (b[1].order ?? 0));
     return [...orderedOptions, ...unorderedOptions];


Reviews:
user: login: jlrobins
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-29T19:37:48Z
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR reduces complexity in event handling, adds test coverage for `deleteConnection()`, and cleans up redundant code flagged by SonarCube.

- Extract SecretStorage change handling into its own method  
- Add tests and better null handling for `deleteConnection()`  
- Remove unneeded returns/assertions and streamline imports

### Reviewed Changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.

<details>
<summary>Show a summary per file</summary>

| File                                     | Description                                                                             |
| ---------------------------------------- | --------------------------------------------------------------------------------------- |
| src/webview/scaffold-form.ts             | Disabled unused‐var linter rules around option ordering                                 |
| src/utils/workerPool.test.ts             | Simplified `assert.throws` call to remove unused variable                               |
| src/sidecar/logging.ts                   | Added NOSONAR comment clarifying regex safety                                          |
| src/flinkSql/flinkStatementManager.ts    | Removed unnecessary `return` statement                                                  |
| src/extension.ts                         | Consolidated Sentry imports                                                             |
| src/errors.ts                            | Simplified parsing logic and removed redundant type assertions                          |
| src/docker/workflows/cp-schema-registry.ts | Removed unnecessary `await` on synchronous helper                                      |
| src/docker/workflows/confluent-local.ts  | Deleted unreachable `return`                                                            |
| src/directConnectManager.ts              | Extracted `handleDirectConnectionsChanged`, refactored `deleteConnection()`             |
| src/directConnectManager.test.ts         | Added tests for missing-connection and successful delete scenarios                      |
| src/directConnect.ts                     | Removed redundant `return` statements                                                   |
| src/consume.ts                           | Renamed `envId` to `directEnvId` for clarity                                            |
| src/commands/utils/flinkStatements.ts    | Added NOSONAR comment for timezone‐offset regex                                         |
| src/commands/schemaUpload.ts             | Removed non-null assertion on `registeredVersion`                                       |
| src/commands/index.ts                    | Removed unnecessary `await` in command wrapper                                          |
| src/chat/tools/getConnections.ts         | Suppressed unused `token` parameter                                                      |
| src/chat/participant.ts                  | Simplified redundant type assertion                                                     |
| src/authz/types.ts                       | Removed type assertion when returning operations array                                  |
| src/authn/ccloudProvider.ts              | Removed non-null assertion on `_session` when firing session‐change event               |
</details>



<details>
<summary>Comments suppressed due to low confidence (2)</summary>

**src/authz/types.ts:12**
* The function signature specifies a return type of KafkaTopicOperation[], but validOperations is inferred as string[]. Reintroduce a type assertion or map elements to KafkaTopicOperation to satisfy the declared API.
```
return validOperations;
```
**src/commands/schemaUpload.ts:184**
* Dropping the non-null assertion on registeredVersion may pass undefined to schemaRegistrationMessage, which expects a number. Add a runtime check or restore the assertion to avoid unexpected undefined values.
```
const successMessage = schemaRegistrationMessage(subject, existingVersion, registeredVersion);
```
</details>


state: COMMENTED
author_association: NONE
submitted_at: 2025-05-29T19:40:37Z
user: login: jlrobins
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-29T20:07:21Z
user: login: jlrobins
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-29T20:08:03Z
user: login: shouples
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-29T21:28:20Z
user: login: shouples
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-05-29T21:34:45Z
user: login: shouples
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-29T21:46:06Z

Review comments:
diff_hunk: @@ -27,7 +27,7 @@ export function registerCommandWithLogging(
       ...getCommandArgsContext(args),
     });
     try {
-      return await command(...args);
+      return command(...args);
path: src/commands/index.ts
user: login: jlrobins
body: command isn't async, so lose the no-op await.
created_at: 2025-05-29T19:37:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -513,7 +513,7 @@ export class ConfluentCloudAuthProvider implements vscode.AuthenticationProvider
     } else {
       this._onDidChangeSessions.fire({
         added: [],
-        removed: [this._session!],
+        removed: [this._session],
path: src/authn/ccloudProvider.ts
user: login: Copilot
body: Removed the non-null assertion on this._session may now pass null into the removed array, violating the expected AuthenticationSession[] type. Consider retaining the assertion or adding a guard to ensure _session is not null.
created_at: 2025-05-29T19:40:36Z
author_association: NONE
diff_hunk: @@ -39,7 +39,9 @@ class ScaffoldFormViewModel extends ViewModel {
 
   options = this.derive(() => {
     const allOptions = Object.entries(this.spec()?.options ?? {});
+    // eslint-disable-next-line @typescript-eslint/no-unused-vars
     const orderedOptions = allOptions.filter(([_, details]) => details.order !== undefined);
+    // eslint-disable-next-line @typescript-eslint/no-unused-vars
     const unorderedOptions = allOptions.filter(([_, details]) => details.order === undefined);
path: src/webview/scaffold-form.ts
user: login: Copilot
body: [nitpick] Suppressing unused-variable warnings here could be avoided by renaming the unused parameter (e.g., use [ , details]) or prefixing it with an underscore to improve readability without linter disables.
```suggestion
    const orderedOptions = allOptions.filter(([_, _details]) => _details.order !== undefined);
    const unorderedOptions = allOptions.filter(([_, _details]) => _details.order === undefined);
```
created_at: 2025-05-29T19:40:36Z
author_association: NONE
diff_hunk: @@ -39,7 +39,9 @@ class ScaffoldFormViewModel extends ViewModel {
 
   options = this.derive(() => {
     const allOptions = Object.entries(this.spec()?.options ?? {});
+    // eslint-disable-next-line @typescript-eslint/no-unused-vars
     const orderedOptions = allOptions.filter(([_, details]) => details.order !== undefined);
+    // eslint-disable-next-line @typescript-eslint/no-unused-vars
     const unorderedOptions = allOptions.filter(([_, details]) => details.order === undefined);
path: src/webview/scaffold-form.ts
user: login: Copilot
body: [nitpick] Consider consolidating or removing this duplicate linter disable. Renaming the unused parameter or adjusting the callback signature can eliminate the need for multiple disable comments.
```suggestion
    const orderedOptions = allOptions.filter(([key, details]) => details.order !== undefined);
    const unorderedOptions = allOptions.filter(([key, details]) => details.order === undefined);
```
created_at: 2025-05-29T19:40:37Z
author_association: NONE
diff_hunk: @@ -41,9 +41,7 @@ export async function handleConnectionChange(
   if (!existingConnections) {
     window.showInformationMessage(`Connection "${connection.name}" is disconnected.`);
     directConnectForm.dispose();
-    return;
path: src/directConnect.ts
user: login: jlrobins
body: Sonarcube dislikes unneeded returns.
created_at: 2025-05-29T20:07:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -270,4 +281,45 @@ describe("DirectConnectionManager behavior", () => {
 
     assert.ok(tryToCreateConnectionStub.notCalled);
   });
+
+  describe("deleteConnection()", () => {
path: src/directConnectManager.test.ts
user: login: jlrobins
body: Increase test coverage a little bit more. Method was untested prior.
created_at: 2025-05-29T20:08:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -270,4 +281,45 @@ describe("DirectConnectionManager behavior", () => {
 
     assert.ok(tryToCreateConnectionStub.notCalled);
   });
+
+  describe("deleteConnection()", () => {
+    const TEST_DIRECT_CONNECTION_ID = TEST_DIRECT_CONNECTION.spec.id as ConnectionId;
+
+    let directConnectionManager: DirectConnectionManager;
+
+    beforeEach(() => {
+      // Can only be done after the extension context is set.
+      directConnectionManager = DirectConnectionManager.getInstance();
+    });
+
+    it("should handle if getDirectConnection(id) returned null", async () => {
+      // inject stub.
+      const rm = getResourceManager();
+      sandbox.stub(rm, "getDirectConnection").resolves(null);
+
+      await directConnectionManager.deleteConnection(TEST_DIRECT_CONNECTION_ID);
+    });
+
+    it("should work if getDirectConnection(id) returned a connection", async () => {
+      // inject stub.
+      const rm = getResourceManager();
+      sandbox.stub(rm, "getDirectConnection").resolves(TEST_DIRECT_CONNECTION_FORM_SPEC);
+      const deleteStub = sandbox.stub(rm, "deleteDirectConnection").resolves();
+      const tryToDeleteConnectionStub = sandbox
+        .stub(connections, "tryToDeleteConnection")
+        .resolves({} as any);
+
+      const deregisterInstanceStub = sandbox.stub(ResourceLoader, "deregisterInstance");
+
+      await directConnectionManager.deleteConnection(TEST_DIRECT_CONNECTION_ID);
+      assert.ok(deleteStub.calledOnce);
+      assert.ok(deleteStub.calledWith(TEST_DIRECT_CONNECTION_ID));
+
+      assert.ok(tryToDeleteConnectionStub.calledOnce);
+      assert.ok(tryToDeleteConnectionStub.calledWith(TEST_DIRECT_CONNECTION_ID));
+
+      assert.ok(deregisterInstanceStub.calledOnce);
+      assert.ok(deregisterInstanceStub.calledWith(TEST_DIRECT_CONNECTION_ID));
path: src/directConnectManager.test.ts
user: login: shouples
body: Nit: `sinon.assert.*` for debugging test failures more quickly/easily
created_at: 2025-05-29T21:28:19Z
author_association: CONTRIBUTOR

PR comments:
user: login: sonarqube-confluent[bot]
created_at: 2025-05-29T17:40:30Z
body: ![Passed](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/QualityGateBadge/passed.svg?sanitize=true)

# Analysis Details
## 0 Issues
- ![Bug](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/bug.svg?sanitize=true) 0 Bugs
- ![Vulnerability](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/vulnerability.svg?sanitize=true) 0 Vulnerabilities
- ![Code Smell](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/code_smell.svg?sanitize=true) 0 Code Smells

## Coverage and Duplications
- ![Coverage](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/CoverageChart/90.svg?sanitize=true) 94.40% Coverage (62.90% Estimated after merge)
- ![Duplications](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/Duplications/NoDuplicationInfo.svg?sanitize=true) No duplication information (1.10% Estimated after merge)

**Project ID:** vscode

[View in SonarQube](https://sonarqube.dp.confluent.io/dashboard?id=vscode&pullRequest=1930)


author_association: NONE
user: login: sonarqube-confluent[bot]
created_at: 2025-05-29T19:13:29Z
body: ![Failed](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/QualityGateBadge/failed.svg?sanitize=true)

- 0.00% Coverage on New Code (is less than 80.00%)

# Analysis Details
## 2 Issues
- ![Bug](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/bug.svg?sanitize=true) 0 Bugs
- ![Vulnerability](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/vulnerability.svg?sanitize=true) 1 Vulnerability
- ![Code Smell](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/code_smell.svg?sanitize=true) 1 Code Smell

## Coverage and Duplications
- ![Coverage](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/CoverageChart/0.svg?sanitize=true) 0.00% Coverage (0.00% Estimated after merge)
- ![Duplications](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/Duplications/NoDuplicationInfo.svg?sanitize=true) No duplication information (1.10% Estimated after merge)

**Project ID:** vscode

[View in SonarQube](https://sonarqube.dp.confluent.io/dashboard?id=vscode&pullRequest=1930)


author_association: NONE
user: login: sonarqube-confluent[bot]
created_at: 2025-05-29T19:31:14Z
body: ![Failed](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/QualityGateBadge/failed.svg?sanitize=true)

- 56.10% Coverage on New Code (is less than 80.00%)

# Analysis Details
## 1 Issue
- ![Bug](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/bug.svg?sanitize=true) 0 Bugs
- ![Vulnerability](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/vulnerability.svg?sanitize=true) 1 Vulnerability
- ![Code Smell](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/code_smell.svg?sanitize=true) 0 Code Smells

## Coverage and Duplications
- ![Coverage](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/CoverageChart/50.svg?sanitize=true) 56.10% Coverage (62.90% Estimated after merge)
- ![Duplications](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/Duplications/NoDuplicationInfo.svg?sanitize=true) No duplication information (1.10% Estimated after merge)

**Project ID:** vscode

[View in SonarQube](https://sonarqube.dp.confluent.io/dashboard?id=vscode&pullRequest=1930)


author_association: NONE
user: login: sonarqube-confluent[bot]
created_at: 2025-05-29T19:49:19Z
body: ![Failed](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/QualityGateBadge/failed.svg?sanitize=true)

- 56.10% Coverage on New Code (is less than 80.00%)

# Analysis Details
## 1 Issue
- ![Bug](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/bug.svg?sanitize=true) 0 Bugs
- ![Vulnerability](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/vulnerability.svg?sanitize=true) 1 Vulnerability
- ![Code Smell](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/code_smell.svg?sanitize=true) 0 Code Smells

## Coverage and Duplications
- ![Coverage](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/CoverageChart/50.svg?sanitize=true) 56.10% Coverage (62.90% Estimated after merge)
- ![Duplications](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/Duplications/NoDuplicationInfo.svg?sanitize=true) No duplication information (1.10% Estimated after merge)

**Project ID:** vscode

[View in SonarQube](https://sonarqube.dp.confluent.io/dashboard?id=vscode&pullRequest=1930)


author_association: NONE
user: login: sonarqube-confluent[bot]
created_at: 2025-05-29T20:01:23Z
body: ![Failed](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/QualityGateBadge/failed.svg?sanitize=true)

- 57.10% Coverage on New Code (is less than 80.00%)

# Analysis Details
## 0 Issues
- ![Bug](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/bug.svg?sanitize=true) 0 Bugs
- ![Vulnerability](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/vulnerability.svg?sanitize=true) 0 Vulnerabilities
- ![Code Smell](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/code_smell.svg?sanitize=true) 0 Code Smells

## Coverage and Duplications
- ![Coverage](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/CoverageChart/50.svg?sanitize=true) 57.10% Coverage (62.90% Estimated after merge)
- ![Duplications](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/Duplications/NoDuplicationInfo.svg?sanitize=true) No duplication information (1.10% Estimated after merge)

**Project ID:** vscode

[View in SonarQube](https://sonarqube.dp.confluent.io/dashboard?id=vscode&pullRequest=1930)


author_association: NONE
user: login: sonarqube-confluent[bot]
created_at: 2025-05-29T20:23:47Z
body: ![Failed](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/QualityGateBadge/failed.svg?sanitize=true)

- 57.10% Coverage on New Code (is less than 80.00%)

# Analysis Details
## 0 Issues
- ![Bug](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/bug.svg?sanitize=true) 0 Bugs
- ![Vulnerability](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/vulnerability.svg?sanitize=true) 0 Vulnerabilities
- ![Code Smell](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/code_smell.svg?sanitize=true) 0 Code Smells

## Coverage and Duplications
- ![Coverage](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/CoverageChart/50.svg?sanitize=true) 57.10% Coverage (62.90% Estimated after merge)
- ![Duplications](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/Duplications/NoDuplicationInfo.svg?sanitize=true) No duplication information (1.10% Estimated after merge)

**Project ID:** vscode

[View in SonarQube](https://sonarqube.dp.confluent.io/dashboard?id=vscode&pullRequest=1930)


author_association: NONE
user: login: sonarqube-confluent[bot]
created_at: 2025-05-29T20:33:47Z
body: ![Passed](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/QualityGateBadge/passed.svg?sanitize=true)

# Analysis Details
## 0 Issues
- ![Bug](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/bug.svg?sanitize=true) 0 Bugs
- ![Vulnerability](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/vulnerability.svg?sanitize=true) 0 Vulnerabilities
- ![Code Smell](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/common/code_smell.svg?sanitize=true) 0 Code Smells

## Coverage and Duplications
- ![Coverage](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/CoverageChart/60.svg?sanitize=true) 85.70% Coverage (62.90% Estimated after merge)
- ![Duplications](https://sonarqube.dp.confluent.io/static/communityBranchPlugin/checks/Duplications/NoDuplicationInfo.svg?sanitize=true) No duplication information (1.10% Estimated after merge)

**Project ID:** vscode

[View in SonarQube](https://sonarqube.dp.confluent.io/dashboard?id=vscode&pullRequest=1930)


author_association: NONE
user: login: sentry[bot]
created_at: 2025-06-09T19:22:25Z
body: ## Suspect Issues
This pull request was deployed and Sentry observed the following issues:

- ‼️ **ResponseError: Error 401 "Unauthorized" @ http://127.0.0.1:26636/subjects/dev.real-estate.bc.company.v11-value/versions: confluent.schemas.upload** `logError(src/errors)` [View Issue](https://confluent.sentry.io/issues/6668409732/?referrer=github-pr-bot)

<sub>Did you find this useful? React with a 👍 or 👎</sub>
author_association: NONE