From ec5660d78613352cb618d296f923d6ed086ee542 Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Wed, 6 Aug 2025 21:46:59 +0530 Subject: [PATCH] [ty] Avoid warning for old settings schema too aggresively (#19787) ## Summary This PR avoids warning the users too aggressively by checking the structure of the initialization and workspace options and avoids the warning if they conform to the old schema. ## Test Plan https://github.com/user-attachments/assets/9ade9dc4-90cb-4fd4-abd0-4bc4177df3db --- crates/ty_server/src/server.rs | 32 ++++++++++++++++++------ crates/ty_server/src/session.rs | 31 +++++++++++++++++------ crates/ty_server/tests/e2e/initialize.rs | 12 +++------ 3 files changed, 53 insertions(+), 22 deletions(-) diff --git a/crates/ty_server/src/server.rs b/crates/ty_server/src/server.rs index dc1ea3a2b7..f172d03016 100644 --- a/crates/ty_server/src/server.rs +++ b/crates/ty_server/src/server.rs @@ -98,13 +98,31 @@ impl Server { let (main_loop_sender, main_loop_receiver) = crossbeam::channel::bounded(32); let client = Client::new(main_loop_sender.clone(), connection.sender.clone()); - if !initialization_options.options.unknown.is_empty() { - let options = serde_json::to_string_pretty(&initialization_options.options.unknown) - .unwrap_or_else(|_| "".to_string()); - tracing::warn!("Received unknown options during initialization: {options}"); - client.show_warning_message(format_args!( - "Received unknown options during initialization: {options}" - )); + let unknown_options = &initialization_options.options.unknown; + if !unknown_options.is_empty() { + // HACK: Old versions of the ty VS Code extension used a custom schema for settings + // which was changed in version 2025.35.0. This is to ensure that users don't receive + // unnecessary warnings when using an older version of the extension. This should be + // removed after a few releases. + if !unknown_options.contains_key("settings") + || !unknown_options.contains_key("globalSettings") + { + tracing::warn!( + "Received unknown options during initialization: {}", + serde_json::to_string_pretty(unknown_options) + .unwrap_or_else(|_| format!("{unknown_options:?}")) + ); + + client.show_warning_message(format_args!( + "Received unknown options during initialization: '{}'. \ + Refer to the logs for more details", + unknown_options + .keys() + .map(String::as_str) + .collect::>() + .join("', '") + )); + } } // Get workspace URLs without settings - settings will come from workspace/configuration diff --git a/crates/ty_server/src/session.rs b/crates/ty_server/src/session.rs index e036937e8d..529897f71e 100644 --- a/crates/ty_server/src/session.rs +++ b/crates/ty_server/src/session.rs @@ -458,13 +458,30 @@ impl Session { .clone() .combine(options.clone()); - if !options.unknown.is_empty() { - let options = serde_json::to_string_pretty(&options.unknown) - .unwrap_or_else(|_| "".to_string()); - tracing::warn!("Received unknown options for workspace `{url}`: {options}"); - client.show_warning_message(format!( - "Received unknown options for workspace `{url}`: {options}", - )); + let unknown_options = &options.unknown; + if !unknown_options.is_empty() { + // HACK: This is to ensure that users with an older version of the ty VS Code + // extension don't get warnings about unknown options when they are using a newer + // version of the language server. This should be removed after a few releases. + if !unknown_options.contains_key("importStrategy") + && !unknown_options.contains_key("interpreter") + { + tracing::warn!( + "Received unknown options for workspace `{url}`: {}", + serde_json::to_string_pretty(unknown_options) + .unwrap_or_else(|_| format!("{unknown_options:?}")) + ); + + client.show_warning_message(format!( + "Received unknown options for workspace `{url}`: '{}'. \ + Refer to the logs for more details.", + unknown_options + .keys() + .map(String::as_str) + .collect::>() + .join("', '") + )); + } } combined_global_options.combine_with(Some(global)); diff --git a/crates/ty_server/tests/e2e/initialize.rs b/crates/ty_server/tests/e2e/initialize.rs index 8e07b34f9f..2af0bf2731 100644 --- a/crates/ty_server/tests/e2e/initialize.rs +++ b/crates/ty_server/tests/e2e/initialize.rs @@ -392,8 +392,7 @@ fn unknown_initialization_options() -> Result<()> { let mut server = TestServerBuilder::new()? .with_workspace(workspace_root, None)? .with_initialization_options( - ClientOptions::default() - .with_unknown([("foo".to_string(), Value::String("bar".to_string()))].into()), + ClientOptions::default().with_unknown([("bar".to_string(), Value::Null)].into()), ) .build()? .wait_until_workspaces_are_initialized()?; @@ -403,7 +402,7 @@ fn unknown_initialization_options() -> Result<()> { insta::assert_json_snapshot!(show_message_params, @r#" { "type": 2, - "message": "Received unknown options during initialization: {\n /"foo/": /"bar/"\n}" + "message": "Received unknown options during initialization: 'bar'. Refer to the logs for more details" } "#); @@ -418,10 +417,7 @@ fn unknown_options_in_workspace_configuration() -> Result<()> { let mut server = TestServerBuilder::new()? .with_workspace( workspace_root, - Some( - ClientOptions::default() - .with_unknown([("foo".to_string(), Value::String("bar".to_string()))].into()), - ), + Some(ClientOptions::default().with_unknown([("bar".to_string(), Value::Null)].into())), )? .build()? .wait_until_workspaces_are_initialized()?; @@ -431,7 +427,7 @@ fn unknown_options_in_workspace_configuration() -> Result<()> { insta::assert_json_snapshot!(show_message_params, @r#" { "type": 2, - "message": "Received unknown options for workspace `file:///foo`: {\n /"foo/": /"bar/"\n}" + "message": "Received unknown options for workspace `file:///foo`: 'bar'. Refer to the logs for more details." } "#);