Skip to content

Commit 5fb2eb2

Browse files
bors[bot]matklad
andauthored
Merge #10147
10147: fix: don't panic if the client sends invalid request r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
2 parents f0f0278 + 2d2c4e7 commit 5fb2eb2

File tree

5 files changed

+55
-27
lines changed

5 files changed

+55
-27
lines changed

crates/rust-analyzer/src/from_proto.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ use crate::{
1010
from_json,
1111
global_state::GlobalStateSnapshot,
1212
line_index::{LineIndex, OffsetEncoding},
13-
lsp_ext, Result,
13+
lsp_ext,
14+
lsp_utils::invalid_params_error,
15+
Result,
1416
};
1517

1618
pub(crate) fn abs_path(url: &lsp_types::Url) -> Result<AbsPathBuf> {
@@ -85,7 +87,8 @@ pub(crate) fn annotation(
8587
snap: &GlobalStateSnapshot,
8688
code_lens: lsp_types::CodeLens,
8789
) -> Result<Annotation> {
88-
let data = code_lens.data.unwrap();
90+
let data =
91+
code_lens.data.ok_or_else(|| invalid_params_error("code lens without data".to_string()))?;
8992
let resolve = from_json::<lsp_ext::CodeLensResolveData>("CodeLensResolveData", data)?;
9093

9194
match resolve {

crates/rust-analyzer/src/handlers.rs

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use crate::{
4040
self, InlayHint, InlayHintsParams, PositionOrRange, ViewCrateGraphParams,
4141
WorkspaceSymbolParams,
4242
},
43-
lsp_utils::all_edits_are_disjoint,
43+
lsp_utils::{all_edits_are_disjoint, invalid_params_error},
4444
to_proto, LspError, Result,
4545
};
4646

@@ -767,9 +767,8 @@ pub(crate) fn handle_completion_resolve(
767767
let _p = profile::span("handle_completion_resolve");
768768

769769
if !all_edits_are_disjoint(&original_completion, &[]) {
770-
return Err(LspError::new(
771-
ErrorCode::InvalidParams as i32,
772-
"Received a completion with overlapping edits, this is not LSP-compliant".into(),
770+
return Err(invalid_params_error(
771+
"Received a completion with overlapping edits, this is not LSP-compliant".to_string(),
773772
)
774773
.into());
775774
}
@@ -1038,7 +1037,7 @@ pub(crate) fn handle_code_action_resolve(
10381037
let _p = profile::span("handle_code_action_resolve");
10391038
let params = match code_action.data.take() {
10401039
Some(it) => it,
1041-
None => Err("can't resolve code action without data")?,
1040+
None => return Err(invalid_params_error(format!("code action without data")).into()),
10421041
};
10431042

10441043
let file_id = from_proto::file_id(&snap, &params.code_action_params.text_document.uri)?;
@@ -1056,10 +1055,10 @@ pub(crate) fn handle_code_action_resolve(
10561055
let (assist_index, assist_resolve) = match parse_action_id(&params.id) {
10571056
Ok(parsed_data) => parsed_data,
10581057
Err(e) => {
1059-
return Err(LspError::new(
1060-
ErrorCode::InvalidParams as i32,
1061-
format!("Failed to parse action id string '{}': {}", params.id, e),
1062-
)
1058+
return Err(invalid_params_error(format!(
1059+
"Failed to parse action id string '{}': {}",
1060+
params.id, e
1061+
))
10631062
.into())
10641063
}
10651064
};
@@ -1076,23 +1075,17 @@ pub(crate) fn handle_code_action_resolve(
10761075

10771076
let assist = match assists.get(assist_index) {
10781077
Some(assist) => assist,
1079-
None => return Err(LspError::new(
1080-
ErrorCode::InvalidParams as i32,
1081-
format!(
1082-
"Failed to find the assist for index {} provided by the resolve request. Resolve request assist id: {}",
1083-
assist_index, params.id,
1084-
),
1085-
)
1078+
None => return Err(invalid_params_error(format!(
1079+
"Failed to find the assist for index {} provided by the resolve request. Resolve request assist id: {}",
1080+
assist_index, params.id,
1081+
))
10861082
.into())
10871083
};
10881084
if assist.id.0 != expected_assist_id || assist.id.1 != expected_kind {
1089-
return Err(LspError::new(
1090-
ErrorCode::InvalidParams as i32,
1091-
format!(
1092-
"Mismatching assist at index {} for the resolve parameters given. Resolve request assist id: {}, actual id: {:?}.",
1093-
assist_index, params.id, assist.id
1094-
),
1095-
)
1085+
return Err(invalid_params_error(format!(
1086+
"Mismatching assist at index {} for the resolve parameters given. Resolve request assist id: {}, actual id: {:?}.",
1087+
assist_index, params.id, assist.id
1088+
))
10961089
.into());
10971090
}
10981091
let edit = to_proto::code_action(&snap, assist.clone(), None)?.edit;

crates/rust-analyzer/src/lsp_utils.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,13 @@ use crate::{
88
from_proto,
99
global_state::GlobalState,
1010
line_index::{LineEndings, LineIndex, OffsetEncoding},
11+
LspError,
1112
};
1213

14+
pub(crate) fn invalid_params_error(message: String) -> LspError {
15+
LspError { code: lsp_server::ErrorCode::InvalidParams as i32, message }
16+
}
17+
1318
pub(crate) fn is_cancelled(e: &(dyn Error + 'static)) -> bool {
1419
e.downcast_ref::<Cancelled>().is_some()
1520
}

crates/rust-analyzer/src/to_proto.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ use crate::{
2121
config::Config,
2222
global_state::GlobalStateSnapshot,
2323
line_index::{LineEndings, LineIndex, OffsetEncoding},
24-
lsp_ext, semantic_tokens, Result,
24+
lsp_ext,
25+
lsp_utils::invalid_params_error,
26+
semantic_tokens, Result,
2527
};
2628

2729
pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position {
@@ -1198,7 +1200,9 @@ pub(crate) fn markup_content(markup: Markup) -> lsp_types::MarkupContent {
11981200
}
11991201

12001202
pub(crate) fn rename_error(err: RenameError) -> crate::LspError {
1201-
crate::LspError { code: lsp_server::ErrorCode::InvalidParams as i32, message: err.to_string() }
1203+
// This is wrong, but we don't have a better alternative I suppose?
1204+
// https://github.com/microsoft/language-server-protocol/issues/1341
1205+
invalid_params_error(err.to_string())
12021206
}
12031207

12041208
#[cfg(test)]

docs/dev/style.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,29 @@ fn foo() -> Option<Bar> {
895895

896896
**Rationale:** reduce cognitive stack usage.
897897

898+
Use `return Err(err)` to throw an error:
899+
900+
```rust
901+
// GOOD
902+
fn f() -> Result<(), ()> {
903+
if condition {
904+
return Err(());
905+
}
906+
Ok(())
907+
}
908+
909+
// BAD
910+
fn f() -> Result<(), ()> {
911+
if condition {
912+
Err(())?;
913+
}
914+
Ok(())
915+
}
916+
```
917+
918+
**Rationale:** `return` has type `!`, which allows the compiler to flag dead
919+
code (`Err(...)?` is of unconstrained generic type `T`).
920+
898921
## Comparisons
899922

900923
When doing multiple comparisons use `<`/`<=`, avoid `>`/`>=`.

0 commit comments

Comments
 (0)