microsoft / microsoft/TypeScript

Bad tsserverPath in the unstable/sync API client surfaces as bare "EPIPE: broken pipe, write" instead of naming the executable

Abierto
#63,885 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Possible Improvement
Lenguaje dominante
Go
Estrellas
111k
Forks
14.3k
Merge medio
2 d 4 h
PR fusionados (30 d)
132

Descripción

Version
  • typescript@7.0.2 (gitHead 2bd066d87f5bafd315be9f40889d0a60b9e58e0b),
    @typescript/typescript-linux-x64@7.0.2
  • Node v22.22.0, Linux x86_64 (Fedora 43)
Repro
import { API } from "typescript/unstable/sync";

const api = new API({ tsserverPath: "/nonexistent/binary" });
api.parseConfigFile("/some/tsconfig.json");
Expected

An error identifying the executable, along the lines of the default path's
Executable not found: <path>, or the channel's own
Unexpected EOF while reading from child process (exited with code N).

Actual
Error: EPIPE: broken pipe, write
    at writeSync (node:fs:922:3)
    at SyncRpcChannel.writeAllBuf (.../dist/api/syncChannel.js:495:27)
    at SyncRpcChannel.writeTuple (.../dist/api/syncChannel.js:314:18)
    at SyncRpcChannel.requestBytesSync (.../dist/api/syncChannel.js:221:14)
    at Client.apiRequest (.../dist/api/sync/client.js:58:37)

The same EPIPE appears for any tsserverPath that is not an API server —
/bin/cat and /bin/sleep both produce it — so the message never distinguishes
"executable missing" from "executable is not a tsgo API server".

Analysis
  • resolveExePath (dist/api/options.js) returns options.tsserverPath
    unchecked: return options.tsserverPath ?? getExePath();. The default branch,
    getExePath (lib/getExePath.js), does fs.existsSync(exe) and throws
    Executable not found: <path> — the explicit-path branch has no such check.
  • SyncRpcChannel.writeAllBuf (dist/api/syncChannel.js) catches only
    EAGAIN/EWOULDBLOCK and rethrows everything else raw. The read side has an
    eofError() helper that reports the child's exitCode/signalCode; the write
    side has no equivalent, so a child that died before the first request produces
    the low-level errno instead.
  • The spawn "error" event (ENOENT) is never observed on the child.

A check in resolveExePath mirroring getExePath's existsSync, plus an
EPIPE branch in writeAllBuf that raises the channel's eofError(), would
cover both shapes.

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con resolveExePath en dist/api/options.js y compáralo con getExePath en lib/getExePath.js; después inspecciona SyncRpcChannel.writeAllBuf y eofError en dist/api/syncChannel.js. Vuelve a ejecutar el ejemplo proporcionado de sync API con /nonexistent/binary y un ejecutable que no sea un servidor; se considera terminado cuando los errores identifican el ejecutable o la salida del proceso hijo, en lugar de exponer un EPIPE sin más.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
node.js, typescript
Área
api, backend
Tipo de issue
Error
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Tranquilo
Claridad
Bien especificado
Aptitud para principiantes
70/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.