Skip to content

feat: Language Client handles error and loading states

Description

This MR adds loading and error states to the Language Client state management.

The tricky part in this MR is refactoring that changes the state management from combination of boolean flags and state machine (temporary state) to only boolean flags:

From

stateDiagram-v2
    state "boolean flags" as permanent {
         state "disabled in settings" as DisabledSettings
         state "disabled by user" as DisabledUser
         state "unsupported language" as Unsupported
         state "no account" as NoAccunt  
    }
    state "state diagram" as temporary {
        Ready --> Loading
        Loading --> Ready
        Loading --> Error
        Error --> Loading
    }

To

stateDiagram-v2
    state "boolean flags" as permanent {
         state "disabled in settings" as DisabledSettings
         state "disabled by user" as DisabledUser
         state "unsupported language" as Unsupported
         state "no account" as NoAccunt
         Error
         Loading
         Ready
    }

This is because when communicating with LS, the completion requests are separate from error signalling.


This MR is made is best-reviewed commit-by-commit.

Commits explained

  1. refactor: isEnabled suggestion state was only referring to user settings
    • change isEnabled state to isDisabeldByUser
    • the isEnabled was used only for the toggle command to know if suggestions are disabled by the user (omitting other reasons why the suggestions might not work, like API error or unsupported language)
    • the isEnabled was confusing because the suggestions could still not work (unsupported file language) but the isEnabled was true
  2. refactor: change suggestion state management to flags only
    • we still used the temporary state to indicate API loading and error
    • when connecting to the LS, the error and loading become disconnected (LS sends error notifications when the circuit breaker triggers, but normal requests for completion can't return an error)
    • in future commits we always switch the state to loading when we request completion, but if the circuit breaker engages, we also switch the error flag to true and the error flag will take precedence
    • in other words, it's possible for API to be in an error state but at the same time we request new completion and switch state to loading
  3. feat: show loading state for LS suggestions
  4. feat: language server suggestions react to api errors

Related Issues

Partially implements: #1052 (closed)

How has this been tested?

Language Server

  1. Apply the following patch to LS to iterate between 5 successful and 5 failed API requests

    diff --git a/src/common/message_handler.ts b/src/common/message_handler.ts
    index a3184e5..aa060a5 100644
    --- a/src/common/message_handler.ts
    +++ b/src/common/message_handler.ts
    @@ -71,6 +71,8 @@ export class MessageHandler {
     
       #subscriptions: Disposable[] = [];
     
    +  #requestCounter = 0;
    +
       constructor({
         configProvider,
         api,
    @@ -245,6 +247,10 @@ export class MessageHandler {
           console.warn('Code suggestions were not requested as the circuit breaker is open.');
           return [];
         }
    +    this.#requestCounter++;
    +    if (this.#requestCounter % 10 > 4) {
    +      throw new Error('Fake error');
    +    }
     
         const context = this.#documents.getContext(
           textDocument.uri,
  2. link your LS project with the extension so your development extension uses the local LS

  3. Disable code suggestions in your settings and make sure you use the non-LS implementation

    {
      "gitlab.aiAssistedCodeSuggestions.enabled": false,
      "gitlab.featureFlags.languageServer":true,
    }
  4. See that when you ask for suggestions, after 4 failed suggestion requests, the state switches to API error

  5. See that loading state works

loading-and-error

non-LS implementation

  1. Disable code suggestions in your settings and make sure you use the non-LS implementation

    {
      "gitlab.aiAssistedCodeSuggestions.enabled": false,
      "gitlab.featureFlags.languageServer":false,
    }
  2. Go to JS file and type something in

    • see suggestions coming in and the status icon showing the loading state when suggestions are loading

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation
  • Chore (Related to CI or Packaging to platforms)
  • Test gap
Edited by Tomas Vik (OOO back on 2024-06-18)

Merge request reports