rcjsuen / dockerfile-language-server

A language server for Dockerfiles powered by Node.js, TypeScript, and VSCode technologies.
MIT License
372 stars 15 forks source link

Unrecognized URI scheme causes confusing error message to be returned #232

Closed rcjsuen closed 5 years ago

rcjsuen commented 5 years ago

With the code below, we are able to start the language server and then send a textDocument/definition request to it. We use an unrecognized uri://dockerfile/x.txt URI as the text document identifier.

import * as net from "net"
import * as child_process from "child_process"

let messageId = 1;

function send(socket: net.Socket, method: string, params: object) {
    let message = {
        jsonrpc: "2.0",
        id: messageId++,
        method: method,
        params: params
    };
    let json = JSON.stringify(message) + "\n";
    let headers = "Content-Length: " + json.length + "\r\n\r\n";
    socket.write(headers, "ASCII");
    socket.write(json, "UTF-8");
}

function initialize(socket: net.Socket) {
    send(socket, "initialize", {
        rootPath: process.cwd(),
        processId: process.pid,,
        capabilities: {
            textDocument: {
                /* ... */
            },
            workspace: {
                /* ... */
            }
        }
    });
}

function definition(socket: net.Socket) {
    send(socket, "textDocument/definition", {
        textDocument: {
            uri: "uri://dockerfile/x.txt"
        },
        position: {
            line: 0,
            character: 1
        }
    });
}

const server = net.createServer((socket: net.Socket) => {
    server.close();
    socket.on("data", (data) => {
        let message = data.toString();
        let idx = message.indexOf('{');
        if (idx !== -1) {
            message = message.substring(message.indexOf('{'));
            console.log(message);
            console.log();
        }
    });
    initialize(socket);
    definition(socket);
});

server.listen(3000, () => {
    child_process.spawn("node", [ "out/src/server.js", "--socket=3000" ]);
});

When you run the code, you will get a strange error back. The output has been formatted for readability purposes.

{
  "jsonrpc": "2.0",
  "id": 2,
  "error": {
    "code": -32603,
    "message": "Request textDocument/definition failed with message: path must be a string or Buffer"
  }
}

The reason is because file is undefined in the code below. The fs.exists function does not like it so it throws an error back at the caller. https://github.com/rcjsuen/dockerfile-language-server-nodejs/blob/17693c2c5aeb6c2693e033f2c136fc113e57f09e/src/server.ts#L72-L81