`ChildProcess.spawn` crashes the program when the program to spawn cannot be started
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 2/5
- Temps estimé
- 1-3 heures
- Accessibilité débutants
- 78/100
- Type d'issue
- Bug
- Clarté
- Clairement spécifiée
- Activité
- Active
- Stack technique
- javascript
- Domaine
- backend
Piste de recherche
Commencez dans Gren/Kernel/ChildProcess.js et comparez le chemin de spawn asynchrone avec le bloc catch synchrone décrit dans l’issue. Exécutez la reproduction liée avec les commandes gren make et node fournies. C’est terminé lorsqu’un processus NoShell impossible à démarrer ne fait plus planter Node et que son échec est transmis via onExit.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
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),
),
),
);
- Langage dominant
- JavaScript
- Étoiles
- 13
- Forks
- 6
- Merge moyen
- 4 j 10 h
- PR mergées (30 j)
- 4
Préparer son environnement
Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de gren-lang/node
-
bug
Difficulté 2/5 1-3 heures Accessibilité débutants 86/100
-
`ChildProcess.spawn` with `NoShell` looks for a program named after the program and its argumentsOuvertebug
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
-
breaking enhancement
Difficulté 3/5 1-2 jours Accessibilité débutants 42/100
-
breaking bug
Difficulté 3/5 1-2 jours Accessibilité débutants 64/100
-
bug
Difficulté 3/5 1-2 jours Accessibilité débutants 74/100
Toutes les issues de gren-lang/node
Issues similaires
-
[Bug] @deck.gl/arcgis dist import resolves to unpublished @deck.gl/core source path (9.3.11, 9.4.0)Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100
stac-utils/stac-fields#42 ·
-
[sec-check] SVG remote-reference gate misses src attributes, link hrefs and bare-string @importOuverteagent/security hive/hosted-available-lke648397-260827-5n31 security
Difficulté 2/5 1-3 heures Accessibilité débutants 88/100
Les mainteneurs répondent en général sous 1 jour
-
Fix #3381 does not fix #3343: watch() returns the ref, not the value, so setup() never re-runsOuverte
Difficulté 2/5 1-3 heures Accessibilité débutants 86/100
Les mainteneurs répondent en général sous 1 jour
-
Add: Eurosport 1 PolskaOuvertechannels:add check:passed
Difficulté 1/5 Moins d'une heure Accessibilité débutants 75/100
Les mainteneurs répondent en général sous 2 jours