Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

serve-instrument exits when an instrument directory is deleted or a request URL has a malformed percent-escape

オープン
#1,804 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
82/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
node.js, typescript
領域
backend, testing

調査の方向性

Start with packages/serve-instrument/src/server.tsx at the watcher callback, updateEncodedBundle, request handler, and URL decoding points named in the issue. Then read packages/serve-instrument/src/__tests__/server.test.ts and run the focused tests. Done when the deletion and malformed-URL cases return the expected responses without stopping the server or disrupting other instruments.

索引モデルが issue の本文から書いたものです。

説明

Area: Instruments Bug Difficulty: Low Good First Issue Priority: Low

serve-instrument exits with an unhandled error when an instrument directory is deleted or renamed while it runs, or when it receives a URL with a malformed percent-escape. In both cases an exception escapes an async function that is called with void: this.handler.handle(...) for requests, and this.updateEncodedBundle() in the fs.watch callback. Node turns the unhandled rejection into a process exit. In updateEncodedBundle, only the bundle() call is inside the try; the readdir/readFile before it are not. In --all mode, deleting or renaming one instrument folder kills the server for all the others, and so does a git checkout that removes one. An author has to notice that the terminal died and restart it.

Where

packages/serve-instrument/src/server.tsx:45-48, 62-79 and 243-247, 312:

    this.watcher = fs.watch(target, { recursive: false }, () => {
      // ...
      void this.updateEncodedBundle();
    });
// ...
  private async updateEncodedBundle(): Promise<void> {
    const inputs: BundlerInput[] = [];
    const filepaths = await fs.promises
      .readdir(this.target, 'utf-8')
      // ...
    for (const filepath of filepaths) {
      const loader = inferLoader(filepath);
      const content: string | Uint8Array = await fs.promises.readFile(filepath, /* ... */);
      // ...
    }
    const start = Date.now();
    try {
// ...
      const decodedName = decodeURIComponent(name!);
// ...
    this.server = http.createServer((...args) => void this.handler.handle(...args));

Reproduce

  1. Build it (pnpm --filter @opendatacapture/serve-instrument build) and run node dist/cli.js --all <dir> on a directory containing forms/FOO/index.ts and forms/BAR/index.ts.
  2. Open /forms/BAR, then rm -rf <dir>/forms/BAR.
    Actual: ↺ [forms/BAR] File changed, rebuilding..., then Error: ENOENT: no such file or directory, scandir '…/forms/BAR' and the process exits (verified on main). /forms/FOO is no longer served.
  3. Restart, then curl 'http://localhost:3000/forms/%E0%A4%A'.
    Actual: URIError: URI malformed at decodeURIComponent and the process exits (verified on main).

Expected: the server logs the failure and keeps running. A deleted instrument answers 404 and a malformed URL answers 400.

Tests

packages/serve-instrument/src/__tests__/server.test.ts:

  • it('should keep serving other instruments after an instrument directory is deleted, so a rebuild failure does not kill the server'): fire the captured watch callback after removing the temp directory, and assert that the remaining instrument still returns 200.
  • it('should answer 400 to a malformed percent-escape in an instrument URL rather than crashing')

No e2e test applies: serve-instrument is not part of the stack under testing/.

Suggested fix

Move the directory listing and file reads inside the existing try in updateEncodedBundle. Wrap handle in Server's request callback with a .catch that logs the error and ends the response with 500 if headers are not yet sent. Map a URIError from decodeURIComponent to 400.

主要言語
TypeScript
スター
119
フォーク
19
平均マージ
1日 4時間
マージ済み PR(30日)
44

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

DouglasNeuroInformatics/OpenDataCapture のほかの issue

DouglasNeuroInformatics/OpenDataCapture の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。