`ChildProcess.spawn` crashes the program when the program to spawn cannot be started
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 2/5
- Geschätzter Aufwand
- 1-3 Stunden
- Anfängerfreundlichkeit
- 78/100
- Issue-Typ
- Bug
- Klarheit
- Klar beschrieben
- Aktivitätsstatus
- Aktiv
- Tech-Stack
- javascript
- Bereich
- backend
Rechercherichtung
Beginne in Gren/Kernel/ChildProcess.js und vergleiche den asynchronen Spawn-Pfad mit dem im Issue beschriebenen synchronen Catch-Block. Führe die verlinkte Reproduktion mit den bereitgestellten gren make- und node-Befehlen aus. Als abgeschlossen gilt die Änderung, wenn ein nicht startbarer NoShell-Prozess Node nicht mehr zum Absturz bringt und sein Fehler über onExit zugestellt wird.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Found against: gren 0.6.6, gren-lang/core 7.4.2, gren-lang/node 6.1.3, node 22
Reproduction: https://github.com/gilramir/gren-bug-reports/tree/main/2026-09-16-childprocess-spawn-error-crashes
ChildProcess.spawn with NoShell whose program cannot be started (it does
not exist, or is not executable) ends the whole Gren program with node's
Unhandled 'error' event. Neither onExit nor the connection message arrives,
so the application cannot handle the failure. With DefaultShell the shell
starts, fails to find the program and exits 127, which onExit receives.
Reproduction
gren.json dependencies: gren-lang/core 7.4.2, gren-lang/node 6.1.3. Save as src/Main.gren. Build and run with gren make Main --output=app && node app:
module Main exposing (main)
import Bytes exposing (Bytes)
import ChildProcess exposing (Shell(..))
import Init
import Node
import Stream
import Task
rows : Array { label : String, shell : Shell, program : String, arguments : Array String }
rows =
[ { label = "`DefaultShell`, `no-such-program`", shell = DefaultShell, program = "no-such-program", arguments = [] }
, { label = "`NoShell`, `no-such-program`", shell = NoShell, program = "no-such-program", arguments = [] }
]
type Msg
= Spawn Int
| Exited { row : Int, code : Int }
| Started
type alias Model =
{ cp : ChildProcess.Permission, stdout : Stream.Writable Bytes }
main : Node.Program Model Msg
main =
Node.defineProgram { init = init, update = update, subscriptions = \_ -> Sub.none }
init : Node.Environment -> Init.Task { model : Model, command : Cmd Msg }
init env =
Init.await ChildProcess.initialize <| \cp ->
Node.startProgram
{ model = { cp = cp, stdout = env.stdout }
, command = print env.stdout "| spawn | exit code | expected |\n|---|---|---|" (Spawn 0)
}
print : Stream.Writable Bytes -> String -> Msg -> Cmd Msg
print stdout line next =
Stream.writeLineAsBytes line stdout |> Task.attempt (\_ -> next)
update : Msg -> Model -> { model : Model, command : Cmd Msg }
update msg model =
when msg is
Spawn i ->
{ model = model
, command =
when Array.get i rows is
Just r ->
ChildProcess.spawn model.cp r.program r.arguments
{ shell = r.shell
, workingDirectory = ChildProcess.InheritWorkingDirectory
, environmentVariables = ChildProcess.InheritEnvironmentVariables
, runDuration = ChildProcess.NoLimit
, connection = ChildProcess.Ignored (\_ -> Started)
, onExit = \code -> Exited { row = i, code = code }
}
Nothing ->
Cmd.none
}
Exited { row = i, code } ->
{ model = model
, command =
when Array.get i rows is
Just r ->
print model.stdout ("| " ++ r.label ++ " | " ++ String.fromInt code ++ " | non-zero |") (Spawn (i + 1))
Nothing ->
Cmd.none
}
Started ->
{ model = model, command = Cmd.none }
Output:
$ node app
| spawn | exit code | expected |
|---|---|---|
| `DefaultShell`, `no-such-program` | 127 | non-zero |
node:events:497
throw er; // Unhandled 'error' event
^
Error: spawn no-such-program ENOENT
at ChildProcess._handle.onexit (node:internal/child_process:285:19)
at onErrorNT (node:internal/child_process:483:16)
at process.processTicksAndRejections (node:internal/process/task_queues:89:21)
Emitted 'error' event on ChildProcess instance at:
at ChildProcess._handle.onexit (node:internal/child_process:291:12)
at onErrorNT (node:internal/child_process:483:16)
at process.processTicksAndRejections (node:internal/process/task_queues:89:21) {
errno: -2,
code: 'ENOENT',
syscall: 'spawn no-such-program',
path: 'no-such-program',
spawnargs: []
}
Node.js v22.23.2
Cause
Node reports a failed spawn asynchronously, as an error event on the
ChildProcess, and Gren/Kernel/ChildProcess.js installs no listener for it;
an error event with no listener throws. The kernel handles only a spawn that
throws synchronously, by sending onExit the error's errno:
} catch (e) {
callback(
__Scheduler_succeed(
__Scheduler_rawSpawn(
sendExitToApp(typeof e.errno === "undefined" ? -1 : e.errno),
),
),
);
- Vorherrschende Sprache
- JavaScript
- Sterne
- 13
- Forks
- 6
- Ø Merge
- 4 T. 10 Std.
- Gemergte PRs (30 T.)
- 4
Entwicklungsumgebung
Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus gren-lang/node
-
breaking enhancement
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 38/100
-
breaking enhancement
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 42/100
-
breaking bug
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 64/100
-
enhancement
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 48/100
-
enhancement
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 48/100
Ähnliche Issues
-
refactor
Schwierigkeit 2/5 Ein halber Tag Anfängerfreundlichkeit 84/100
Maintainer antworten meist innerhalb von 5 Tagen
-
translation
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
ciderapp/translations#87 · 1 Kommentar ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 88/100
Maintainer antworten meist innerhalb von 1 Tag
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 67/100
Maintainer antworten meist innerhalb von 1 Tag
-
component: split-view platform: windows
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100
zen-browser/desktop#15616 · 1 Reaktion ·
Maintainer antworten meist innerhalb von 1 Tag