microsoft / python-language-server

Microsoft Language Server for Python
Apache License 2.0
910 stars 130 forks source link

Monaco JS: Error: Object reference not set to an instance of an object. #2136

Closed palkerecsenyi closed 2 years ago

palkerecsenyi commented 3 years ago

Environment data

Expected behaviour

I'm trying to set up Python Language Server to connect to an instance of the Monaco editor running on a website. The server doesn't have the code stored on it, and I'm using monaco-languageclient to send the user's Python code as an in-memory file. I'd like the frontend Monaco editor to support Python Language Server's LSP functionality.

Actual behaviour

I get the following error message the moment the Monaco editor loads:

Error: Object reference not set to an instance of an object.

Logs

[Info  - 16:10:52] Analysis cache path: /root/.cache/Microsoft/Python Language Server
[Info  - 16:10:52] Microsoft Python Language Server version 1.0.0.0
[Info  - 16:10:52] Workspace root: 
[Error - 16:10:54] Request textDocument/codeAction failed.
Error: The task was cancelled.
Error: Object reference not set to an instance of an object.
A request has failed. See the output for more information.
Uncaught Error: Object reference not set to an instance of an object.

There is nothing else logged on the server.

Code Snippet / Additional information

React frontend ```typescript import { CloseAction, createConnection, ErrorAction, MonacoLanguageClient, MonacoServices, } from 'monaco-languageclient'; import { listen, MessageConnection } from 'vscode-ws-jsonrpc'; import getEnvVariable from './getEnv'; import { TaskLanguage } from '../types'; function createLanguageClient(connection: MessageConnection) { return new MonacoLanguageClient({ name: 'lsp.palcode.dev', clientOptions: { documentSelector: ['python', 'shell'], errorHandler: { error: () => ErrorAction.Continue, closed: () => CloseAction.DoNotRestart, } }, connectionProvider: { get(errorHandler, closeHandler) { return Promise.resolve(createConnection( // @ts-ignore connection, errorHandler, closeHandler, )); } } }); } type DisposeFunction = () => void; export default function connectToLanguageServer( language: TaskLanguage, ): undefined | DisposeFunction { const lspURL = getEnvVariable('LSP'); if (!lspURL) { return; } try { MonacoServices.get(); } catch (e) { // @ts-ignore MonacoServices.install(require('monaco-editor-core/esm/vs/platform/commands/common/commands').CommandsRegistry); } // in this case, language is 'python' const webSocket = new WebSocket(lspURL + '/' + language); webSocket.onerror = () => {}; let pingInterval: number; listen({ webSocket, onConnection: (connection) => { const client = createLanguageClient(connection); const disposable = client.start(); connection.onClose(() => disposable.dispose()); connection.onError(() => {}); pingInterval = window.setInterval(() => { webSocket.send('ping'); }, 20000); }, }); return () => { try { webSocket.close(); clearInterval(pingInterval); } catch (e) {} }; } ```
Node.JS backend ```typescript import * as http from 'http'; import ws from 'ws'; import * as url from 'url'; import * as rpc from 'vscode-ws-jsonrpc'; import * as server from 'vscode-ws-jsonrpc/lib/server'; import * as lsp from 'vscode-languageserver'; function launch(socket: rpc.IWebSocket, command: string, args: string[]) { const reader = new rpc.WebSocketMessageReader(socket); const writer = new rpc.WebSocketMessageWriter(socket); const socketConnection = server.createConnection(reader, writer, () => socket.dispose()); const serverConnection = server.createServerProcess('JSON', command, args); server.forward(socketConnection, serverConnection, message => { if (rpc.isRequestMessage(message)) { if (message.method === lsp.InitializeRequest.type.method) { const initializeParams = message.params; initializeParams.processId = process.pid; } } return message; }); } const httpServer = http.createServer((req, res) => { // required for health checks res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write(''); res.end(); }).listen(process.env.PORT); const socketServers: { [path: string]: ws.Server, } = {}; const languages = [ { command: '/opt/python-language-server/output/bin/Release/Microsoft.Python.LanguageServer', args: [], path: '/python', }, { command: 'bash-language-server', args: ['start'], path: '/bash', }, ]; for (const language of languages) { const socket = new ws.Server({ perMessageDeflate: false, noServer: true, }); socket.on('connection', (client) => { const iWebSocket = { send: (content: any) => client.send(content), onMessage: (cb: (message: ws.Data) => void) => client.onmessage = event => { if (event.data !== 'ping') { cb(event.data); } }, onError: (cb: (message: string) => void) => client.onerror = event => { if ('message' in event) { cb(event.message) } }, onClose: (cb: (code: number, reason: string) => void) => client.onclose = event => cb(event.code, event.reason), dispose: () => client.close(), }; launch(iWebSocket, language.command, language.args); }); socketServers[language.path] = socket; } httpServer.on('upgrade', (request, socket, head) => { const pathname = url.parse(request.url).pathname; if (!pathname) { socket.destroy(); return; } const socketServer = socketServers[pathname]; if (!socketServer) { socket.destroy(); return; } socketServer.handleUpgrade(request, socket, head, (ws) => { socketServer.emit('connection', ws, request); }); }); ```
abhi211199 commented 2 years ago

Hey @palkerecsenyi , did you find a fix for this issue?

judej commented 2 years ago

Thank you for the report. This project is no longer active. If you are using the Python language server in VSCode, the language server you are using is Pylance and please the http://github.com/microsoft/pylance-release to report issues.

If you are using Visual Studio, then, please use http://github.com/microsoft/PTVS to report issues.

thank you