microsoft / microsoft/TypeScript

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

Đang mở
#63,885 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Possible Improvement
Ngôn ngữ chính
Go
Star
111k
Fork
14.3k
Merge trung bình
2 ngày 4 giờ
Pull request đã merge (30 ngày)
132

Mô tả

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.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu với resolveExePath trong dist/api/options.js và so sánh nó với getExePath trong lib/getExePath.js, sau đó kiểm tra SyncRpcChannel.writeAllBuf và eofError trong dist/api/syncChannel.js. Chạy lại ví dụ sync API được cung cấp với /nonexistent/binary và một tệp thực thi không phải máy chủ; được xem là hoàn tất khi các lỗi xác định tệp thực thi hoặc việc tiến trình con thoát, thay vì để lộ một EPIPE đơn thuần.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
node.js, typescript
Lĩnh vực
api, backend
Loại issue
Lỗi
Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
70/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.