Skip to content
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

Use default config on missing configuration section #459

Merged
merged 1 commit into from
Feb 4, 2021

Conversation

aufarg
Copy link
Contributor

@aufarg aufarg commented Oct 3, 2020

Hi, I've made a change to make default configuration to be used if initializationOptions doesn't have haskell or languageServerHaskell key in it. There are some issue where the server returns haskell-lsp: configuration parse error.. This change shouldn't break any existing configuration because it adds safety net instead of straight failing.

Also, I actually made the same change to haskell/haskell-ide-engine#1802 first before realizing there's a new project. I'm not sure if this can be considered as bug fix, so I'll keep it open there.

@aufarg aufarg force-pushed the return-default-on-empty-init-option branch 2 times, most recently from 993f4a8 to c3c0499 Compare October 4, 2020 05:34
src/Ide/Main.hs Outdated
t <- t
hPutStrLn stderr $ "Started LSP server in " ++ showDuration t
sessionLoader <- loadSession dir
-- config <- fromMaybe defaultLspConfig <$> getConfig
config <- fromMaybe def <$> getConfig
Copy link
Member

@jneira jneira Dec 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about dont add the DefaultConfig constructor, keeping the actual definition and only check here that there is no client config doing a pattern matching on Maybe.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we make the parsing always successful, I believe getConfig will never return Nothing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm starting to think that to add alert message that we fallback to default config will require a change in haskell-lsp instead around these lines here. There should be a way for us to specify the default config when parsing error occurs.

pepeiborra added a commit that referenced this pull request Dec 27, 2020
* Suggest missing imports via package exports map

At the expense of some space and initialization time, suggest imports now is
able to find suggestions in all the packages available to the project.

* BadDependency - include the key in the error message

* remove the assumption that the GhcSession is always available

* fix bad spacing

Co-Authored-By: Moritz Kiefer <moritz.kiefer@purelyfunctional.org>

* Add type annotation to clarify rule being defined

* Remove file dependency from PackageExports rule

* Guess patterns

Co-authored-by: Moritz Kiefer <moritz.kiefer@purelyfunctional.org>
@jneira
Copy link
Member

jneira commented Jan 11, 2021

Hi, there is a recent open issue about that (#1196) and the fix is already here so i think we have to unblock this.
I dont fully like the change in the Config data type and not sure if there could be another alternative to signal the client is providing an empty config.

// cc @Hogeyama @aufarg @Ailrun

@pepeiborra
Copy link
Collaborator

pepeiborra commented Jan 11, 2021

Hi, there is a recent open issue about that (#1196) and the fix is already here so i think we have to unblock this.
I dont fully like the change in the Config data type and not sure if there could be another alternative to signal the client is providing an empty config.

// cc @Hogeyama @aufarg @Ailrun

How do we know that this fix works? I see no test

Comment on lines 51 to 53
data Config
= DefaultConfig
| UserConfig Bool Bool Int Int Bool Bool Bool T.Text
Copy link
Collaborator

@pepeiborra pepeiborra Jan 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not good enough. Please restore the field names or use Haddock comments to label the fields

@pepeiborra
Copy link
Collaborator

The parser should be able to handle the empty object, since that's a valid configuration as all the configuration flags are optional. On the other hand, if a field is the wrong type, the parser should fail and HLS should error out.

The approach taken by this PR is reasonable, but the implementation is a bit convoluted. I would handle this by making all the configuration fields optional, which is equivalent but easier to understand.

@aufarg
Copy link
Contributor Author

aufarg commented Jan 12, 2021

Hi, there is a recent open issue about that (#1196) and the fix is already here so i think we have to unblock this.
I dont fully like the change in the Config data type and not sure if there could be another alternative to signal the client is providing an empty config.
// cc @Hogeyama @aufarg @Ailrun

How do we know that this fix works? I see no test

Sorry I haven't write the test because I wasn't sure if it should be done like this. I'll add the tests soon.

@aufarg
Copy link
Contributor Author

aufarg commented Jan 16, 2021

The parser should be able to handle the empty object, since that's a valid configuration as all the configuration flags are optional. On the other hand, if a field is the wrong type, the parser should fail and HLS should error out.

The approach taken by this PR is reasonable, but the implementation is a bit convoluted. I would handle this by making all the configuration fields optional, which is equivalent but easier to understand.

I actually have a question for the suggested approach here. I'm quite new to Haskell so I'm not familiar how we do things in Haskell.

So one of the comment I received above asked to make it so if user typed a wrong configuration key, we should print a message. If we make the configuration fields all optional, how do we determine if a value of Config not from user input? Should we check that all the fields are Nothing?

I also have question regarding potential code duplication if we resolve Config until the value is used. Is there maybe a way to resolve the value of Config that will be global from HLS other than in parseConfig?

@pepeiborra
Copy link
Collaborator

The parser should be able to handle the empty object, since that's a valid configuration as all the configuration flags are optional. On the other hand, if a field is the wrong type, the parser should fail and HLS should error out.
The approach taken by this PR is reasonable, but the implementation is a bit convoluted. I would handle this by making all the configuration fields optional, which is equivalent but easier to understand.

I actually have a question for the suggested approach here. I'm quite new to Haskell so I'm not familiar how we do things in Haskell.

So one of the comment I received above asked to make it so if user typed a wrong configuration key, we should print a message. If we make the configuration fields all optional, how do we determine if a value of Config not from user input? Should we check that all the fields are Nothing?

If a user makes a typo in the configuration key, this will not result in an error with the current implementation. Is that what you are asking?

I also have question regarding potential code duplication if we resolve Config until the value is used. Is there maybe a way to resolve the value of Config that will be global from HLS other than in parseConfig?

What do you mean by resolve here? Perhaps this blog post is helpful: https://reasonablypolymorphic.com/blog/higher-kinded-data/

@aufarg
Copy link
Contributor Author

aufarg commented Jan 17, 2021

If a user makes a typo in the configuration key, this will not result in an error with the current implementation. Is that what you are asking?

Yes, and it also does not log any error message. The reason I introduced a new constructor for Config is to differentiate between user config and default config (when we fail to detect user config).

What do you mean by resolve here? Perhaps this blog post is helpful: https://reasonablypolymorphic.com/blog/higher-kinded-data/

Ah this seems to be what I need here. Thanks! I suppose I can also use it to check if the Config is all Nothing, it means we did not detect any configuration from the user.

@pepeiborra
Copy link
Collaborator

If a user makes a typo in the configuration key, this will not result in an error with the current implementation. Is that what you are asking?

Yes, and it also does not log any error message. The reason I introduced a new constructor for Config is to differentiate between user config and default config (when we fail to detect user config).

I would prefer to keep this PR focused, and just fix the issue with { }. We can consider the behaviour on { haskell.thisIsATypo: true} in a separate PR.

@aufarg
Copy link
Contributor Author

aufarg commented Jan 17, 2021

I would prefer to keep this PR focused, and just fix the issue with { }. We can consider the behaviour on { haskell.thisIsATypo: true} in a separate PR.

Actually if it's just fixing the issue with {} I have a previous commit that keeps the record definition here. What do you think?

@pepeiborra
Copy link
Collaborator

Looks good to me

@aufarg aufarg force-pushed the return-default-on-empty-init-option branch from c3c0499 to f875fe6 Compare January 25, 2021 17:27
@aufarg
Copy link
Contributor Author

aufarg commented Jan 25, 2021

@pepeiborra @jneira

Sorry for the delay, took me quite a while to understand lenses for implementing the test. I keep the record definition but it doesn't print any message if the key is not detected for now.

Copy link
Member

@Ailrun Ailrun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM :)

@aufarg aufarg force-pushed the return-default-on-empty-init-option branch 2 times, most recently from e39c054 to 20de9be Compare January 26, 2021 13:27
@aufarg
Copy link
Contributor Author

aufarg commented Jan 26, 2021

Hmm, not sure why my test always timed out on (8.10.3, ubuntu-latest)

@aufarg aufarg force-pushed the return-default-on-empty-init-option branch from 20de9be to 9b21da1 Compare January 31, 2021 06:00
@aufarg
Copy link
Contributor Author

aufarg commented Jan 31, 2021

It seems the server does not always send log notification after config change. I updated the test code to throw dummy response so it'll not block waiting for response.

@aufarg
Copy link
Contributor Author

aufarg commented Feb 3, 2021

@Ailrun Were you about to merge this to master? I see that you make a merge commit to merge master to this branch instead.

@Ailrun
Copy link
Member

Ailrun commented Feb 3, 2021

I'm actually waiting for @jneira's approval. I made the merge commit to check that it still works with many other recent changes.

Copy link
Member

@jneira jneira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm too, thanks for the pr and the patience!

@Ailrun Ailrun added the merge me Label to trigger pull request merge label Feb 3, 2021
@Ailrun
Copy link
Member

Ailrun commented Feb 3, 2021

It looks like some formatter tests fail. Could you check it?

On serving initialize request, deserializing HIE configuration embedded
in InitializeParam passed by client will result in an error if during
process the server cannot find HIE specific configuration key under
initializationOptions.

This commit changes the initializationOptions deserialization to return
the default configuration if configuration key cannot be found under
initializationOptions. Here, setting the key with a value of null will
also be considered as part of not found condition to accommodate clients
that fills missing user options as null.
@aufarg aufarg force-pushed the return-default-on-empty-init-option branch from d1b5b71 to 4fa8c8f Compare February 4, 2021 14:30
@mergify mergify bot merged commit 0fd73f8 into haskell:master Feb 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge me Label to trigger pull request merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants