-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The flow-language-server responds with different error messages for changing files than it does for saving files #7009
Comments
Hi @jbrown215. Currently flow lsp is unusable because of this. Is this on flow team radar? |
This is the first I'm hearing of it; thanks for bringing it to my attention. I wonder if this is something that might be handled as part of @gabelevi's current work. I'll get back to you about this on Tuesday. |
Also,
I'm curious to know how this breaks LSP's usability. Is the issue that LSP is only returning errors on save instead of change? Do the errors get cleared between a |
Yes, after any change errors are cleared and even if not it's too wasteful to save after each change. Especially this is painful when refactoring. |
@jbrown215 I'm testing 0.89 and what I see is that flow diagnostics are being sent only after Note that this is only about type errors as syntax errors are reported by flow just fine on |
Just to elaborate — I don't see the behaviour where errors are being cleared (using flow 0.89 and ALE). |
Although more elaboration — if I do further changes then errors are being cleared so yeah — pretty sad LSP experience! Hope this can be fixed soon! Thank you for looking into this. |
Great, thanks! I'm not very familiar with the LSP implementation and how it should work, so this extra information is very helpful. |
Seems like this is the by-design behaviour for flow/src/commands/lspCommand.ml Lines 711 to 720 in 99e9433
|
"It's a feature." |
Definitely not a feature. Probably a limitation of the implementation at the time, but it's not clear to me if that limitation still exists. I will have a response for you tomorrow. |
How I understand Flow's current behaviorI'm definitely not an expert in LSP and I've only used it via Atom. My understanding at the moment of LSP and Flow's behavior is thus:
The local copy of the file is used to respond to methods like So we don't really respond to How I understand this issueAs I understand it, this is what is being requested: As a user types in their IDE, the IDE will send Or am I misunderstanding this issue? Is the problem that an incorrectly empty response is being sent after a |
That's correct. With vim/ALE the problem is very visible because the editor continues to show old locations of errors while changes are made to the sources and thus highlighting incorrect locations now. |
I concur. I think that understanding of the issue is correct. |
Hmm, looking closer at ad6688a, I now see that it is updating the error locations but the comment says we're not sending the update errors. @ljw1004 - did you have a reason to avoid sending those updated errors to the IDE? |
I coded this and can explain the design. Short answer 1: If you change your editor to send incremental didChange events like Nuclide/VSCode then I bet you'd find it works satisfactorily. Or if you change the editor's initialization method to have Short answer 2: Flow doesn't have the ability to report typecheck errors for a single file at a time. The only way it can report typecheck errors for a file is by doing a whole-program typecheck, which is triggered by a filesystem change event. (The painful reason is that sometimes you're typechecking file B, and the flow typechecker discovers that one type can't be unified with another, and it reports an error for file A where one of those types was defined. Flow's typechecker doesn't have the "locality" invariant that the entire set of typecheck errors for file A are discovered solely by typechecking file A.) Let's walk through the example by @w0rp. First a file was saved. This triggered the editor to send a didSave event. It also separately caused a file-change on disk which was observed by Watchman and which triggered Flow to do a whole-program typecheck. As a result of this typecheck it reported the error in file A. We don't know whether that error came about from typechecking A, or B, or C. Let's suppose for argument's sake that it came from checking B. Next a didChange event arrived with updated contents for the entire file A. Sure we could ask Flow to re-typecheck file A. But that wouldn't do any good. We'd have to somehow know to typecheck B. That's obviously not feasible (we can't expect Flow to do a global typecheck in response to every keystroke!) So the design of FlowLSP is this:
It does exactly that! My hunch is that you had a didChange which deleted the old span that contained the error squiggle, and then replaced it with a new load of text. Therefore, the error must be deleted until such time as the file is saved again. (You might imagine that Flow could observe that the new text is character-for-character identical to the old text and so figure out that the error squiggle could be restored. But you could more usefully imagine an editor sending only incremental didChange events...) If your editor isn't yet set up to send incremental text edits, then turning off liveSyntaxErrors might be the cheapest option to get something working straight away. |
Sounds like Flow needs to be changed so it can support reporting on files that have changed without them being saved to disk, like TypeScript does. |
I have a good experience with regular flow server. I see errors as I edit not save. Why it works differently with lsp? |
@w0rp I don't think TypeScript is comparable since (1) it doesn't do whole-program error reporting upon edits, (2) it was built from the ground up with the "locality" invariant, one that's quite hard to retrofit. @TrySound What are you describing? Which flow server and which editor? I'm not aware of any ability for Flow to display errors on edit-rather-than-save other than via LSP. |
nvim + ale and non-lsp setup. I see it works via |
@TrySound That's an interesting idea. The check-contents approach would be guaranteed to fail to show certain errors (in particular, the ones reported in file A when encountered by checking file B). That might be good enough. There are two approaches: (1) Users could simply live with their IDE failing to show all errors, because they periodically fall back to the command-line to see all errors. (2) We could make
This approach ends up delivering a nice user-experience in Visual Studio. It means that things are stateful, i.e. it knows which blue errors have so far been deleted due to similar red errors. It requires you to have a good idea for what heuristic to use - generally for you to have written your error messages with the foreknowledge that they will be compared in this way. If the first time red errors come about they're too much different from the existing blue errors then it's a poor user experience. For this reason it's important that red errors get computed promptly upon opening a file. |
Yes, I think that's the right solution, similar to something you might find in say, Eclipse with Java. Update the errors you can, keep the errors you can't prove are gone until a file has been saved again, and then update those errors. |
Hi @ljw1004 any news on this? |
Hey @mroch do you have any news about this issue? |
@ljw1004 I really appreciate the breakdown you've given, and it does indeed seem tricky! I have been switching my Emacs settings to using normal |
Closing since this is by design |
Originally reported here: dense-analysis/ale#2000
If you send a
textDocument/didSave
event to the flow language server, you will get some diagnostic information revealing some type errors, like so:Sending a
textDocument/didChange
event with the contents of the entire file will cause flow to respond with no errors, like so.You can repeat the bug with some LSP clients like ALE with the following project: https://github.com/joeybaker/ale-flow
This seems to be broken since 0.83.0. What
flow
should do instead is return the same error messages in both cases. If there are errors that can only be resolved after saving the file, those errors should be returned in response to thetextDocument/didChange
event until the nexttextDocument/didSave
event is sent.The text was updated successfully, but these errors were encountered: