Return structured StatementRangeError from statement_range()#1040
Open
DavisVaughan wants to merge 1 commit intofeature/statement-range-errorfrom
Open
Return structured StatementRangeError from statement_range()#1040DavisVaughan wants to merge 1 commit intofeature/statement-range-errorfrom
StatementRangeError from statement_range()#1040DavisVaughan wants to merge 1 commit intofeature/statement-range-errorfrom
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Branched from #1028
Goes with posit-dev/positron#11907
When there is a parse error in an R file and the user is trying to execute any code after that parse error, we now return a JsonRPC error with
code = 1and a structureddatafield, wheredata.lineholds the approximate line number of the start of the parse error.The frontend then picks this up by catching when
await this._client.sendRequest(StatementRangeRequest.type, params, token)errors, checking that the caught error haserror.code = 1, and then upcasting the error to a structuredStatementRangeParseErroron the TypeScript side.The end result is that the frontend can now use this to refuse to execute any code, and instead give a pop up notification telling the user where the problem is.
Screen.Recording.2026-02-13.at.3.28.26.PM.mov
It even works in roxygen2! This required adjusting the "sub document"
lineto reflect a line in the original document.Screen.Recording.2026-02-13.at.3.32.38.PM.mov
Note that we use an error code of
1.I believe we are allowed to use any error code not captured by
ErrorCodeshere:https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#responseMessage
I do not think the code number matters much outside of that. Each
Requesttype can have its own set of error codes, and those error codes may overlap with otherRequesttypes.I expect that we may have multiple failure modes in the future, so
StatementRangeParseErroris just the sole enum variant of an overarchingStatementRangeErrortype. This is reflected on the TypeScript side as well.There is very little prior art for returning structured errors from LSP
Requests.There are only two that I know of
InitializeErrorRejection, which is used by theRenameProviderdata.messageis a string with a meaningful reason for rename rejection.The interesting thing about
Rejectionis that once we have left LSP land on the Typescript side, the error path gets merged into the response path as a return value ofRenameLocation & Rejection.We work similarly, but our return value from all of the Typescript APIs is
StatementRange | StatementRangeError, and the way that you know if you have aStatementRangeorStatementRangeErroris the presence of aresult.errorstring field, which also serves as the discriminator for determining the more preciseStatementRangeParseErrorsubtype ofStatementRangeErroritself.