Solución:
NOTA: Este error casi siempre se debe a que el comando no existe, a que el directorio de trabajo no existe oa un error exclusivo de Windows.
Encontré una manera fácil y particular de tener una idea de la causa raíz de:
Error: spawn ENOENT
El problema de este error es que hay muy poca información en el mensaje de error para decirle dónde está el sitio de la llamada, es decir, qué ejecutable / comando no se encuentra, especialmente cuando tiene una base de código grande donde hay muchas llamadas de generación. . Por otro lado, si conocemos el comando exacto que causa el error, podemos seguir la respuesta de @laconbass para solucionar el problema.
Encontré una manera muy fácil de detectar qué comando causa el problema en lugar de agregar detectores de eventos en todas partes en su código como se sugiere en la respuesta de @laconbass. La idea clave es envolver la llamada de generación original con un contenedor que imprima los argumentos enviados a la llamada de generación.
Aquí está la función de envoltura, colóquela en la parte superior de la index.js
o cualquiera que sea el script de inicio de su servidor.
(function() {
var childProcess = require("child_process");
var oldSpawn = childProcess.spawn;
function mySpawn() {
console.log('spawn called');
console.log(arguments);
var result = oldSpawn.apply(this, arguments);
return result;
}
childProcess.spawn = mySpawn;
})();
Luego, la próxima vez que ejecute su aplicación, antes del mensaje de excepción no detectada, verá algo así:
spawn called
{ '0': 'hg',
'1': [],
'2':
{ cwd: '/* omitted */',
env: { IP: '0.0.0.0' },
args: [] } }
De esta manera, puede saber fácilmente qué comando se ejecuta realmente y luego puede averiguar por qué nodejs no puede encontrar el ejecutable para solucionar el problema.
Paso 1: asegúrese spawn
se llama de la manera correcta
Primero, revise los documentos de child_process.spawn (comando, argumentos, opciones):
Lanza un nuevo proceso con lo dado
command
, con argumentos de línea de comando enargs
. Si se omite,args
por defecto es una matriz vacía.El tercer argumento se utiliza para especificar opciones adicionales, cuyo valor predeterminado es:
{ cwd: undefined, env: process.env }
Usar
env
para especificar las variables de entorno que serán visibles para el nuevo proceso, el valor predeterminado esprocess.env
.
Asegúrese de no poner ningún argumento de línea de comando en command
y todo spawn
la llamada es válida. Continúe con el paso siguiente.
Paso 2: identificar el emisor de eventos que emite el evento de error
Busque en su código fuente para cada llamada a spawn
, o child_process.spawn
, es decir
spawn('some-command', [ '--help' ]);
y adjunte allí un detector de eventos para el evento ‘error’, para que se dé cuenta del Emisor de eventos exacto que lo lanza como ‘No controlado’. Después de la depuración, ese controlador se puede eliminar.
spawn('some-command', [ '--help' ])
.on('error', function( err ){ throw err })
;
Ejecute y debería obtener la ruta del archivo y el número de línea donde se registró su oyente de ‘error’. Algo como:
/file/that/registers/the/error/listener.js:29
throw err;
^
Error: spawn ENOENT
at errnoException (child_process.js:1000:11)
at Process.ChildProcess._handle.onexit (child_process.js:791:34)
Si las dos primeras líneas siguen
events.js:72
throw er; // Unhandled 'error' event
repita este paso hasta que no lo estén. Debe identificar el oyente que emite el error antes de continuar con el siguiente paso.
Paso 3: asegúrese de la variable de entorno $PATH
Está establecido
Hay dos escenarios posibles:
- Confías en lo predeterminado
spawn
comportamiento, por lo que el entorno del proceso hijo será el mismo queprocess.env
. - Estás pasando explícitamente un
env
oponerse aspawn
sobre eloptions
argumento.
En ambos escenarios, debe inspeccionar el PATH
clave en el objeto de entorno que utilizará el proceso hijo generado.
Ejemplo para el escenario 1
// inspect the PATH key on process.env
console.log( process.env.PATH );
spawn('some-command', ['--help']);
Ejemplo para el escenario 2
var env = getEnvKeyValuePairsSomeHow();
// inspect the PATH key on the env object
console.log( env.PATH );
spawn('some-command', ['--help'], { env: env });
La ausencia de PATH
(es decir, es undefined
) causará spawn
para emitir el ENOENT
error, ya que no será posible localizar ninguna command
a menos que sea una ruta absoluta al archivo ejecutable.
Cuando PATH
está configurado correctamente, continúe con el paso siguiente. Debe ser un directorio o una lista de directorios. El último caso es el habitual.
Paso 4: asegúrese command
existe en un directorio de los definidos en PATH
El engendro puede emitir el ENOENT
error si el nombre del archivo command
(es decir, ‘algún comando’) no existe en al menos uno de los directorios definidos en PATH
.
Localice el lugar exacto de command
. En la mayoría de las distribuciones de Linux, esto se puede hacer desde una terminal con la which
mando. Le dirá la ruta absoluta al archivo ejecutable (como arriba), o le dirá si no se encuentra.
Ejemplo de uso de which y su salida cuando un comando es fundar
> which some-command
some-command is /usr/bin/some-command
Ejemplo de uso de which y su salida cuando un comando es extraviado
> which some-command
bash: type: some-command: not found
Los programas mal instalados son la causa más común de extraviado mando. Consulte la documentación de cada comando si es necesario e instálelo.
Cuando el comando es un archivo de secuencia de comandos simple, asegúrese de que sea accesible desde un directorio en el PATH
. Si no es así, muévalo a uno o cree un enlace a él.
Una vez que determine PATH
está configurado correctamente y command
es accesible desde él, debería poder generar su proceso hijo sin spawn ENOENT
siendo arrojado.
Como lo señaló @DanielImfeld, se lanzará ENOENT si especifica “cwd” en las opciones, pero el directorio dado no existe.